package com.xbongbong.pro.message.service.impl;

import com.alibaba.dingtalk.openapi.exception.OApiException;
import com.alibaba.dingtalk.openapi.helper.AuthHelper;
import com.alibaba.dingtalk.openapi.helper.Env;
import com.alibaba.dingtalk.openapi.helper.MessageHelper;
import com.alibaba.dingtalk.openapi.message.LightAppMessageDelivery;
import com.alibaba.dingtalk.openapi.newmessage.entity.AbstractMessage;
import com.alibaba.dingtalk.openapi.newmessage.entity.Msg;
import com.alibaba.dingtalk.openapi.newmessage.entity.OA;
import com.alibaba.dingtalk.openapi.newmessage.entity.template.TemplateMessage;
import com.alibaba.dingtalk.openapi.newmessage.helper.CorpConversationHelper;
import com.alibaba.dingtalk.openapi.newmessage.helper.SendToConversationHelper;
import com.alibaba.dingtalk.openapi.newmessage.helper.TemplateMessageTransferHelper;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.message.domain.entity.PushEntity;
import com.xbongbong.message.domain.entity.PushSetEntity;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.TimeConstant;
import com.xbongbong.paas.domain.entity.PaasAppEntity;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.OptionalRangeEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.elasticsearch.util.XbbElasticsearchRestTemplate;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.OptionalRangeEnum;
import com.xbongbong.paas.enums.StageTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.model.PaasAppModel;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.pojo.StageFindPojo;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.ThreadPoolHelper;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.util.URLEncodeUtils;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.pro.config.ProBaseConfig;
import com.xbongbong.pro.constant.CommonConstant;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.MessageErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.message.SendMessageUtil;
import com.xbongbong.pro.message.constant.ContractPushConstant;
import com.xbongbong.pro.message.constant.CustomerPushConstant;
import com.xbongbong.pro.message.constant.OpportunityPushConstant;
import com.xbongbong.pro.message.constant.QuotationPushConstant;
import com.xbongbong.pro.message.constant.WorkReportPushConstant;
import com.xbongbong.pro.message.enums.MessagePushRefTypeEnum;
import com.xbongbong.pro.message.enums.MessageWebPcUrlEnum;
import com.xbongbong.pro.message.enums.PushObjectTypeEnum;
import com.xbongbong.pro.message.enums.PushTimeTypeEnum;
import com.xbongbong.pro.message.enums.PushTypeEnum;
import com.xbongbong.pro.message.feign.SalesReportFeignClient;
import com.xbongbong.pro.message.help.PushHelper;
import com.xbongbong.pro.message.model.PushModel;
import com.xbongbong.pro.message.model.PushSetModel;
import com.xbongbong.pro.message.pojo.PushRefTypePojo;
import com.xbongbong.pro.message.pojo.dto.MessageExpiredReminderDTO;
import com.xbongbong.pro.message.pojo.dto.MessageRabbitMqDTO;
import com.xbongbong.pro.message.pojo.dto.MessageSaveAllTargetDataDTO;
import com.xbongbong.pro.message.pojo.dto.MessageSendToConversationDTO;
import com.xbongbong.pro.message.pushset.ContractRemindPushSet;
import com.xbongbong.pro.message.pushset.CustomerAttrPushSet;
import com.xbongbong.pro.message.pushset.OpportunityPushSet;
import com.xbongbong.pro.message.pushset.QuotationRemindPushSet;
import com.xbongbong.pro.message.pushset.WorkReportOverduePushSet;
import com.xbongbong.pro.message.pushset.WorkReportRemindPushSet;
import com.xbongbong.pro.message.service.MessageNewService;
import com.xbongbong.pro.message.service.MessageService;
import com.xbongbong.pro.message.service.PushService;
import com.xbongbong.pro.message.thread.ExpiredReminderThread;
import com.xbongbong.pro.message.thread.PushDataThread;
import com.xbongbong.pro.message.thread.ReportTargetDataThread;
import com.xbongbong.pro.service.stage.StageFindStrategy;
import com.xbongbong.pro.service.stage.factory.StageFindFactory;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.WorkReportSetEntity;
import com.xbongbong.saas.domain.entity.ext.ContractEntityExt;
import com.xbongbong.saas.domain.entity.ext.CustomerEntityExt;
import com.xbongbong.saas.domain.entity.ext.OpportunityEntityExt;
import com.xbongbong.saas.domain.entity.ext.ProductEntityExt;
import com.xbongbong.saas.domain.entity.ext.QuotationEntityExt;
import com.xbongbong.saas.domain.entity.ext.WorkReportEntityExt;
import com.xbongbong.saas.enums.DingtalkPageUrlEnum;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.WorkReportDeadDayTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.QuotationEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.enums.business.WorkReportFieldEnum;
import com.xbongbong.saas.enums.business.WorkReportTypeEnum;
import com.xbongbong.saas.model.ContractModel;
import com.xbongbong.saas.model.ContractUserModel;
import com.xbongbong.saas.model.CustomerModel;
import com.xbongbong.saas.model.CustomerUserModel;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.model.OpportunityModel;
import com.xbongbong.saas.model.OpportunityUserModel;
import com.xbongbong.saas.model.PayPlanModel;
import com.xbongbong.saas.model.PaymentModel;
import com.xbongbong.saas.model.ProductModel;
import com.xbongbong.saas.model.PurchaseUserModel;
import com.xbongbong.saas.model.QuotationModel;
import com.xbongbong.saas.model.QuotationUserModel;
import com.xbongbong.saas.model.WorkReportModel;
import com.xbongbong.saas.model.WorkReportSetModel;
import com.xbongbong.sys.domain.entity.CompanyEntity;
import com.xbongbong.sys.domain.entity.DepartmentEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.help.SysEnvHelp;
import com.xbongbong.sys.model.CompanyConfigModel;
import com.xbongbong.sys.model.CompanyModel;
import com.xbongbong.sys.model.DepartmentModel;
import com.xbongbong.sys.model.FeeCompanyModel;
import com.xbongbong.sys.model.TargetLogModel;
import com.xbongbong.sys.model.UserModel;
import org.apache.lucene.util.NamedThreadFactory;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.rangeQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * 消息推送相关实现
 * @author 魏荣杰
 * @date 2019/2/26 10:06
 * @since v1.0
 * @version v1.0
 */
@Service("messageService")
public class MessageServiceImpl implements MessageService {
    private static final Logger LOG = LoggerFactory
            .getLogger(MessageServiceImpl.class);

    /**
     * 推送设置线程池
     */
    private static ExecutorService mAllPushExecutor;
    /**
     * 销售简报线程池
     */
    private static ExecutorService mTargetDataExecutor;
    /**
     * 到期提醒线程池
     */
    private static ExecutorService mExpiredReminderExecutor;


    @Resource
    private CompanyModel companyModel;
    @Resource
    private UserModel userModel;
    @Resource
    private PushSetModel pushSetModel;
    @Resource
    private PushModel pushModel;
    @Resource
    private CustomerModel customerModel;
    @Resource
    private PaymentModel paymentModel;
    @Resource
    private ContractUserModel contractUserModel;
    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private TargetLogModel targetLogModel;
    @Resource
    private PushService pushService;
    @Resource
    private ProBaseConfig proBaseConfig;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private CustomerUserModel customerUserModel;
    @Resource
    private ContractModel contractModel;
    @Resource
    private OpportunityModel opportunityModel;
    @Resource
    private OpportunityUserModel opportunityUserModel;
    @Resource
    private AuthHelper authHelper;
    @Resource
    private MessageNewService messageNewService;
    @Resource
    private PushHelper pushHelper;
    @Resource
    private PaasAppModel paasAppModel;
    @Resource
    private EsHelper esHelper;
    @Resource
    private SalesReportFeignClient salesReportFeignClient;
    @Resource
    private ProductModel productModel;
    @Resource
    private QuotationModel quotationModel;
    @Resource
    private QuotationUserModel quotationUserModel;
    @Resource
    private PayPlanModel payPlanModel;
    @Resource
    private PurchaseUserModel purchaseUserModel;
    @Resource
    private WorkReportModel workReportModel;
    @Resource
    private WorkReportSetModel workReportSetModel;
    @Resource
    private DepartmentModel departmentModel;
    @Resource
    private FeeCompanyModel feeCompanyModel;
    @Resource
    private XbbElasticsearchRestTemplate xbbElasticsearchRestTemplate;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private TemplateMessageTransferHelper templateMessageTransferHelper;
    @Resource
    private IndexTypeModel indexTypeModel;
    @Resource
    private SysEnvHelp sysEnvHelp;

    @Override
    public void customerBusinessToPush(String corpid) throws XbbException {
        PaasAppEntity paasAppEntitiy = paasAppModel.getByAlias(XbbRefTypeEnum.CRM.getAlias(), corpid);
        if (paasAppEntitiy == null) {
            LOG.error("customerBusinessToPush crm应用没有，获取appid失败， corpid= " + corpid);
            return;
        }

        if (pushCheck(corpid, PushTypeEnum.CUSTOMER_REMIND)) {
            LOG.info("customerBusinessToPush 客户自定义提醒数据已生成，　corpid=" + corpid);
            return;
        }

        List<PaasFormEntityExt> paasFormEntityList = paasFormModel.getEnableFormListDistributor(corpid, RedundantTemplateTypeEnum.CUSTOMER.getCode(), 0);

        Set<Long> formIds = paasFormEntityList.stream().map(PaasFormEntity::getMirrorFormId).collect(Collectors.toSet());

        List<PaasFormExplainEntity> paasFormExplainEntityList = paasFormExplainModel.getByFormIdIn(formIds, corpid);

        Map<Long, Map<String, FieldAttrEntity>> explainFormIdAndMap = new HashMap<>();
        Map<Long, List<String>> attrFormIdAndMap = new HashMap<>();
        for (PaasFormExplainEntity paasFormExplainEntity : paasFormExplainEntityList) {
            List<FieldAttrEntity> fieldAttrEntities = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);

            // 存放自定义时间类型的字段解释map
            Map<String, FieldAttrEntity> explainMap = new HashMap<>();
            List<String> attrList = new ArrayList<>();
            for (FieldAttrEntity fieldAttrEntity : fieldAttrEntities) {
                if (Objects.equals(fieldAttrEntity.getIsOpen(), BasicConstant.ONE) && Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.DATETIME.getType()) && Objects.equals(fieldAttrEntity.getIsRedundant(), 1)) {
                    explainMap.put(fieldAttrEntity.getAttr(), fieldAttrEntity);
                    attrList.add(fieldAttrEntity.getAttr());
                }
            }

            explainFormIdAndMap.put(paasFormExplainEntity.getFormId(), explainMap);
            attrFormIdAndMap.put(paasFormExplainEntity.getFormId(), attrList);
        }

        Map<Long, List<PushSetEntity>> pushSetMap = new HashMap<>();
        for (Map.Entry<Long, List<String>> entry : attrFormIdAndMap.entrySet()) {
            Long key = entry.getKey();
            List<String> value = entry.getValue();

            CustomerAttrPushSet customerAttrPushSet = new CustomerAttrPushSet();
            List<PushSetEntity> pushSetList = customerAttrPushSet.getPushSetList(corpid, PushTypeEnum.CUSTOMER_REMIND.getCode(), pushSetModel, value, key);

            for (PushSetEntity pushSetEntity : pushSetList) {
                pushSetMap.computeIfAbsent(pushSetEntity.getTemplateId(), v -> new ArrayList<>()).add(pushSetEntity);
            }
        }


        for (PaasFormEntityExt formEntityExt : paasFormEntityList) {
            Long formId = formEntityExt.getId();

            Map<String, FieldAttrEntity> attrMap = explainFormIdAndMap.get(formId);

            List<PushSetEntity> pushSetList = pushSetMap.get(formId);

            for (PushSetEntity pushSetEntity : pushSetList) {

                if (Objects.equals(pushSetEntity.getEnable(), 0) || !attrMap.containsKey(pushSetEntity.getAttrEntity())) {
                    continue;
                }
                FieldAttrEntity fieldAttrEntity = attrMap.get(pushSetEntity.getAttrEntity());

                JSONObject pushTimeObject = JSONObject.parseObject(pushSetEntity.getPushTime());

                //计算存在业务表中的时间 ？？？？-MM-dd，取有效的后几位，2016-11-22 则取-11-22

                Integer timeType = pushTimeObject.getInteger("timeType");
                Integer period = pushTimeObject.getInteger("period");
                // 凌晨执行，计算出当天推送的信息
                Long pushTime = DateTimeUtil.getTodayInt();
                Long businessTime = pushTime;

                if (timeType == null) {
                    LOG.error("timeType is null");
                } else if (timeType == PushTimeTypeEnum.ADVANCE.getCode()) {
                    businessTime = pushTime + period;
                } else if (PushTimeTypeEnum.DELAYED.getCode() == timeType) {
                    businessTime = pushTime - period;
                }
                String businessTimeStr = DateTimeUtil.getDateStringEpochSecond(businessTime);
                if (StringUtil.isEmpty(businessTimeStr)) {
                    continue;
                }
                //时间条件获取完成
                String showTime = businessTimeStr.substring(businessTimeStr.length() - 5, businessTimeStr.length());
                String attr = pushSetEntity.getAttrEntity();

                List<CustomerEntityExt> customerList = new ArrayList<>();
                try {
                    Long startTime =DateTimeUtil.getTodayInt(businessTime);
                    Long endTime = startTime + 86400;
                    BoolQueryBuilder filter = boolQuery()
                            .filter(termQuery("corpid.keyword", corpid))
                            .filter(termQuery("del", 0))
                            .filter(termQuery("formId", formId))
                            .filter(rangeQuery("data." + attr).gte(startTime).lt(endTime))
                            .filter(termsQuery("flowStatus", Arrays.asList(FlowStatusEnum.NOT_NEED_APPROVAL.getType(), FlowStatusEnum.PASS.getType())));
                    List<String> fieldList = new ArrayList<>();
                    fieldList.add(FieldTypeEnum.DATAID.getAlias());
                    IndexTypeEnum indexTypeEnum = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
                    List<PaasFormDataEntityExt> esEntities = esHelper.findByScroll(indexTypeEnum, filter, PaasFormDataEntityExt.class, fieldList);
                    Set<Long> ids = new HashSet<>();
                    for (PaasFormDataEntityExt esEntity : esEntities) {
                        ids.add(esEntity.getDataId());
                    }
                    Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    param.put("ids", ids);
                    param.put("corpid", corpid);
                    param.put("del", 0);
                    customerList = customerModel.findEntitys(param);
                } catch (Exception e) {
                    //es 出错转数据库
                    customerList = customerModel.getCustomerByDateInOneDay(corpid, attr, formId, businessTime);
                }

                if (customerList == null || customerList.size() == 0) {
                    continue;
                }

                //设定早上8点推送 此处为脚本  推送目标为满足条件的所有人，不存在操作人的概念
                pushTime = pushTime + 28800;
                for (CustomerEntityExt customerEntity : customerList) {
                    //推送内容
                    String attrName = fieldAttrEntity.getAttrName();
                    JSONObject customerDataObject = customerEntity.getData();
                    if (customerDataObject != null) {
                        String customerName = customerDataObject.getString(CustomerManagementEnum.NAME.getAttr());
                        String pushObjectStr = pushSetEntity.getPushObject();
                        JSONObject pushObject = JsonHelperUtil.parseObject(pushObjectStr);
                        String typeStr = pushObject.getString("type");
                        JSONArray typeArray = JsonHelperUtil.parseArray(typeStr);
                        List<String> pushUserIdList = new ArrayList<>();
                        List<String> customerMainUserIds = new ArrayList<>();
                        for (Object object : typeArray) {
                            JSONObject jsonObject = (JSONObject) object;
                            Integer enable = jsonObject.getInteger("enable");
                            if (Objects.equals(enable, 1)) {
                                String alias = jsonObject.getString("alias");
                                if (Objects.equals(alias, PushObjectTypeEnum.MAINUSER.getAlias())) {
                                    customerMainUserIds = customerUserModel.getCustomerUserIdList(corpid, Collections.singletonList(customerEntity.getId()), 1);
                                    pushUserIdList.addAll(customerMainUserIds);
                                }
                                if (Objects.equals(alias, PushObjectTypeEnum.COLLABORATOR.getAlias())) {
                                    pushUserIdList.addAll(customerUserModel.getCustomerUserIdList(corpid, Collections.singletonList(customerEntity.getId()), 0));
                                }
                            }
                        }

                        List<UserEntity> userMainEntityList = new ArrayList<>();
                        if (customerMainUserIds.size() > 0) {
                            userMainEntityList = userModel.getByUserIdIn(corpid, customerMainUserIds, true);
                        }

                        for (UserEntity userEntity : userMainEntityList) {
                            pushUserIdList = pushHelper.getPushUserIdList(userEntity, pushObjectStr, pushUserIdList, null);
                        }

                        UserEntity userEntity = new UserEntity();
                        userEntity.setCorpid(corpid);
                        userEntity.setDepartment("[]");
                        pushUserIdList = pushHelper.getPushUserIdList(userEntity, pushObjectStr, pushUserIdList, null);

                        if (pushUserIdList == null || pushUserIdList.isEmpty()) {
                            continue;
                        }

                        OA.Body.Form form = new OA.Body.Form();
                        form.setKey(attrName);
                        form.setValue(showTime);
                        MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO();
                        messageRabbitMqDTO.setCorpid(corpid);
                        messageRabbitMqDTO.setRefIds(Collections.singletonList(customerEntity.getId()));
                        messageRabbitMqDTO.setRemind(0);
                        messageRabbitMqDTO.setPushTime(pushTime);
                        messageRabbitMqDTO.setForm(Collections.singletonList(form));
                        messageRabbitMqDTO.setTitle(String.format(I18nMessageUtil.getMessage(CustomerPushConstant.CUSTOMER_ATTR_TITLE), attrName));
                        messageRabbitMqDTO.setContent(String.format(I18nMessageUtil.getMessage(CustomerPushConstant.CUSTOMER_ATTR), customerName, attrName));
                        messageRabbitMqDTO.setUserIds(pushUserIdList);

                        PushRefTypePojo.Options options = new PushRefTypePojo.Options();
                        options.setAppId(customerEntity.getAppId());
                        options.setMenuId(customerEntity.getMenuId());
                        options.setFormId(customerEntity.getFormId());
                        options.setDataId(customerEntity.getId());
                        options.setBusinessType(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
                        options.setSaasMark(SaasMarkEnum.SAAS.getCode());
                        messageRabbitMqDTO.setOptions(options);

                        try {
                            insertPushData(messageRabbitMqDTO, PushTypeEnum.CUSTOMER_REMIND);
                        } catch (XbbException e) {
                            LOG.warn("MessageServiceImpl.customerBusinessToPush insertPushDate失败，corpid= " + corpid + ", message= " + messageRabbitMqDTO.toString(), e);
                        }
                    }

                }
            }

        }

    }

    @Override
    public void contractBusinessToPush(String corpid) {
        if (Objects.equals(corpid, "dingf9e3733874fe9a7d35c2f4657eb6378f") || Objects.equals(corpid, "ding3ad1f42cbc876913")) {
            LOG.info("com.xbongbong.pro.message.service.impl.MessageServiceImpl.contractBusinessToPush start, corpid=" + corpid);
        }
        if (pushCheck(corpid, PushTypeEnum.CONTRACT_REMIND)) {
            LOG.info("contractBusinessToPush 合同到期提醒数据已生成，　corpid=" + corpid);
            return;
        }
        ContractRemindPushSet contractRemindPushSet = new ContractRemindPushSet();
        PushSetEntity pushSetEntity = contractRemindPushSet.getPushSet(corpid, PushTypeEnum.CONTRACT_REMIND.getSubCode(), pushSetModel);
        if (Objects.equals(pushSetEntity.getEnable(), 0)) {
            return;
        }
        // 计算存在业务表中的时间 ？？？？-MM-dd，取有效的后几位，2016-11-22 则取-11-22
        JSONObject pushTimeObject = JSONObject.parseObject(pushSetEntity.getPushTime());
        Integer timeType = pushTimeObject.getInteger("timeType");
        Integer period = pushTimeObject.getInteger("period");
        // 凌晨执行，计算出当天推送的信息
        Long pushTime = DateTimeUtil.getTodayInt();
        Long businessTime = pushTime;
        if (timeType == PushTimeTypeEnum.ADVANCE.getCode()) {
            businessTime = pushTime + period;
        } else if (timeType == PushTimeTypeEnum.DELAYED.getCode()) {
            businessTime = pushTime - period;
        }

        List<ContractEntityExt> contractList = new ArrayList<>();
        Long startDeadlineTime = DateTimeUtil.getTodayInt(businessTime);
        Long endDeadlineTime = startDeadlineTime + 86400;
        try {
            BoolQueryBuilder filter = boolQuery()
                    .filter(termQuery("corpid.keyword", corpid))
                    .filter(termQuery("del", 0))
                    .filter(termsQuery("flowStatus", Arrays.asList(FlowStatusEnum.NOT_NEED_APPROVAL.getType(), FlowStatusEnum.PASS.getType())))
                    .filter(rangeQuery("data." + ContractEnum.DEADLINE.getAttr()).gte(startDeadlineTime).lt(endDeadlineTime));
            List<String> fieldList = new ArrayList<>();
            fieldList.add(FieldTypeEnum.DATAID.getAlias());
            List<PaasFormDataEntityExt> esEntities = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_CONTRACT, filter, PaasFormDataEntityExt.class, fieldList);
            Set<Long> ids = new HashSet<>();
            for (PaasFormDataEntityExt esEntity : esEntities) {
                ids.add(esEntity.getDataId());
            }
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("idIn", ids);
            param.put("del", 0);
            contractList = contractModel.findEntitys(param);
        } catch (Exception e) {
            //es 出错转数据库
            contractList = contractModel.getContractByDeadlineTime(corpid, startDeadlineTime, endDeadlineTime);
        }
        if (Objects.equals(corpid, "dingf9e3733874fe9a7d35c2f4657eb6378f")  || Objects.equals(corpid, "ding3ad1f42cbc876913")) {
            LOG.info("com.xbongbong.pro.message.service.impl.MessageServiceImpl.contractBusinessToPush,corpid= " + corpid + ", contractList=" + JSON.toJSONString(contractList));
        }
        pushTime += 28800;
        for (ContractEntityExt contract : contractList) {
            JSONObject contractDataObject = contract.getData();
            if (contractDataObject != null) {
                String customerName = contractDataObject.getString(ContractEnum.LINK_CUSTOMER_HIDE.getAttr());
                String contractName = contractDataObject.getString(ContractEnum.NAME.getAttr());
                Integer deadlineTime = contractDataObject.getInteger(ContractEnum.DEADLINE.getAttr());
                String signUserId = contractDataObject.getString(ContractEnum.SIGN_PERSON.getAttr());
                //推送内容
                String content = String.format(I18nMessageUtil.getMessage(ContractPushConstant.CONTRACT_REMIND_CONTENT), customerName, contractName, DateUtil.getDateString(deadlineTime));
                String deadlineStr = DateUtil.getDateString(deadlineTime);

                List<String> mainUserIdList = new ArrayList<>();
                List<String> pushUserIdList = new ArrayList<>();

                String pushObjectStr = pushSetEntity.getPushObject();
                JSONObject pushObject = JsonHelperUtil.parseObject(pushObjectStr);
                String typeString = pushObject.getString("type");
                JSONArray typeJsonArray = JsonHelperUtil.parseArray(typeString);

                for (Object object : typeJsonArray) {
                    JSONObject jsonObject = (JSONObject) object;
                    Integer enable = jsonObject.getInteger("enable");
                    if (Objects.equals(enable, 1)) {
                        String alias = jsonObject.getString("alias");
                        if (Objects.equals(alias, PushObjectTypeEnum.MAINUSER.getAlias())) {
                            pushUserIdList.addAll(contractUserModel.getContractUserIdList(corpid, contract.getId(), 1));
                            mainUserIdList.addAll(pushUserIdList);
                        }
                        if (Objects.equals(alias, PushObjectTypeEnum.COLLABORATOR.getAlias())) {
                            pushUserIdList.addAll(contractUserModel.getContractUserIdList(corpid, contract.getId(), 0));
                        }
                        if (Objects.equals(alias, PushObjectTypeEnum.CONTRACT_SIGNING.getAlias())) {
                            pushUserIdList.add(signUserId);
                        }
                    }
                }

                if (mainUserIdList != null && mainUserIdList.size() > 0) {
                    Map<String, Object> paramUser = new HashMap<>(16);
                    paramUser.put("corpid", corpid);
                    paramUser.put("del", 0);
                    paramUser.put("userIdIn", mainUserIdList);
                    List<UserEntity> userEntityList = userModel.findEntitys(paramUser);
                    for (UserEntity userEntity : userEntityList) {
                        pushUserIdList = pushHelper.getPushUserIdList(userEntity, pushObjectStr, pushUserIdList, null);
                    }
                }

                UserEntity userEntity = new UserEntity();
                userEntity.setCorpid(corpid);
                userEntity.setDepartment("[]");
                pushUserIdList = pushHelper.getPushUserIdList(userEntity, pushObjectStr, pushUserIdList, null);

                MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO();
                messageRabbitMqDTO.setCorpid(corpid);
                messageRabbitMqDTO.setUserIds(pushUserIdList);
                messageRabbitMqDTO.setRefIds(Collections.singletonList(contract.getId()));
                messageRabbitMqDTO.setRemind(0);
                messageRabbitMqDTO.setPushTime(pushTime);
                messageRabbitMqDTO.setTitle(I18nMessageUtil.getMessage(ContractPushConstant.CONTRACT_REMIND_TITLE));
                messageRabbitMqDTO.setContent(content);
                OA.Body.Form form = new OA.Body.Form();
                form.setKey(I18nMessageUtil.getMessage(I18nStringConstant.EXPIRE_DATE));
                form.setValue(deadlineStr);
                messageRabbitMqDTO.setForm(Collections.singletonList(form));

                PushRefTypePojo.Options options = new PushRefTypePojo.Options();
                options.setAppId(contract.getAppId());
                options.setMenuId(contract.getMenuId());
                options.setFormId(contract.getFormId());
                options.setDataId(contract.getId());
                options.setBusinessType(XbbRefTypeEnum.CONTRACT.getCode());
                options.setSaasMark(SaasMarkEnum.SAAS.getCode());
                messageRabbitMqDTO.setOptions(options);

                try {
                    insertPushData(messageRabbitMqDTO, PushTypeEnum.CONTRACT_REMIND);
                } catch (XbbException e) {
                    LOG.warn("MessageServiceImpl.contractBusinessToPush insertPushData出错,corpid= " + corpid + ", message= " + messageRabbitMqDTO.toString(), e);
                }
            }
        }
        if (Objects.equals(corpid, "dingf9e3733874fe9a7d35c2f4657eb6378f") || Objects.equals(corpid, "ding3ad1f42cbc876913")) {
            LOG.info("com.xbongbong.pro.message.service.impl.MessageServiceImpl.contractBusinessToPush finish, corpid=" + corpid);
        }

/*        for (ContractEntityExt contract : contractList) {
            JSONObject contractDataObject = JsonHelperUtil.parseObject(contract.getData());
            String customerName = contractDataObject.getString(ContractEnum.LINK_CUSTOMER.getAttr());
            String contractName = contractDataObject.getString(ContractEnum.NAME.getAttr());
            Integer deadlineTime = contractDataObject.getInteger(ContractEnum.DEADLINE.getAttr());
            String signUserId = contractDataObject.getString(ContractEnum.SIGN_PERSON.getAttr());
            //推送内容
            String content = String.format(ContractPushConstant.CONTRACT_REMIND, customerName, contractName, DateUtil.getString(businessTime, DateUtil.SDFDate));
            String deadlineStr = DateUtil.getDateString(deadlineTime);

            JSONObject msgObject = new JSONObject();
            msgObject.put("到期时间", deadlineStr);

            List<String> mainUserIdList = new ArrayList<>();
            List<String> pushUserIdList = new ArrayList<>();

            String pushObjectStr = pushSetEntity.getPushObject();
            JSONObject pushObject = JsonHelperUtil.parseObject(pushObjectStr);
            String typeString = pushObject.getString("type");
            JSONArray typeJsonArray = JsonHelperUtil.parseArray(typeString);

            for (Object object : typeJsonArray) {
                JSONObject jsonObject = (JSONObject) object;
                Integer enable = jsonObject.getInteger("enable");
                if (Objects.equals(enable, 1)) {
                    String alias = jsonObject.getString("alias");
                    if (Objects.equals(alias, PushObjectTypeEnum.MAINUSER.getAlias())) {
                        pushUserIdList.addAll(contractUserModel.getContractUserIdList(corpid, contract.getId(), 1));
                        mainUserIdList.addAll(pushUserIdList);
                    }
                    if (Objects.equals(alias, PushObjectTypeEnum.COLLABORATOR.getAlias())) {
                        pushUserIdList.addAll(contractUserModel.getContractUserIdList(corpid, contract.getId(), 0));
                    }
                    if (Objects.equals(alias, PushObjectTypeEnum.CONTRACT_SIGNING.getAlias())) {
                        pushUserIdList.add(signUserId);
                    }
                }
            }

            if (mainUserIdList != null && mainUserIdList.size() > 0) {
                Map<String, Object> paramUser = new HashMap<>(16);
                paramUser.put("corpid", corpid);
                paramUser.put("del", 0);
                paramUser.put("userIdIn", mainUserIdList);
                List<UserEntity> userEntityList = userModel.findEntitys(paramUser);
                for (UserEntity userEntity : userEntityList) {
                    pushUserIdList = pushService.getPushUserIdList(userEntity, pushObjectStr, pushUserIdList, null);
                }
            }

            UserEntity userEntity = new UserEntity();
            userEntity.setCorpid(corpid);
            userEntity.setDepartment("[]");
            pushUserIdList = pushService.getPushUserIdList(userEntity, pushObjectStr, pushUserIdList, null);

            pushTime += 28800;
            pushService.delayedPush(corpid, pushUserIdList, ContractPushConstant.CONTRACT_REMIND_TITLE, content, RefEntityEnum.CONTRACT_ENTITY, contract.getId(), PushTypeEnum.CONTRACT_REMIND, pushTime, msgObject);

        }*/

    }

    @Override
    public void opportunityBusinessToPush(String corpid) {
        // 如果今天的到期机会已经生成了，则不再重复生成
        if (pushCheck(corpid, PushTypeEnum.OPPORTUNITY_EXPIRE_PUSH)) {
            LOG.info("opportunityBusinessToPush 销售机会到期提醒数据已生成，　corpid=" + corpid);
            return;
        }
        OpportunityPushSet opportunityPushSet = new OpportunityPushSet();
        PushSetEntity pushSetEntity = opportunityPushSet.getPushSet(corpid, PushTypeEnum.OPPORTUNITY_EXPIRE_PUSH.getSubCode(), pushSetModel);
        if (Objects.equals(pushSetEntity.getEnable(), 0)) {
            return;
        }
        JSONObject pushTimeObject = JSONObject.parseObject(pushSetEntity.getPushTime());
        Integer timeType = pushTimeObject.getInteger("timeType");
        Integer period = pushTimeObject.getInteger("period");

        Long pushTime = DateTimeUtil.getTodayInt();
        Long businessTime = pushTime;
        if (Objects.equals(PushTimeTypeEnum.ADVANCE.getCode(), timeType)) {
            businessTime = pushTime + period;
        }

        Long startEstimateEndTime = DateTimeUtil.getTodayInt(businessTime);
        Long endEstimateEndTime = startEstimateEndTime + 86400;
        List<OpportunityEntityExt> opportunityList;
        try {
            StageFindStrategy stageFindStrategy = StageFindFactory.getStageFindStrategy(XbbRefTypeEnum.SALES_OPPORTUNITY.getCode());
            Set<String> saleStageCodeIn = stageFindStrategy.findStageCodeList(corpid, new StageFindPojo(StageTypeEnum.getOrdinaryType()));
            BoolQueryBuilder filter = boolQuery()
                    .filter(termQuery("corpid.keyword", corpid))
                    .filter(termQuery("del", 0))
                    .filter(termsQuery("flowStatus", Arrays.asList(FlowStatusEnum.NOT_NEED_APPROVAL.getType(), FlowStatusEnum.PASS.getType())))
                    .filter(rangeQuery("data." + SalesOpportunityEnum.ESTIMATE_END_TIME.getAttr()).gte(startEstimateEndTime).lt(endEstimateEndTime))
                    .filter(boolQuery().filter(termsQuery(SalesOpportunityEnum.getEsAttr4Keyword(SalesOpportunityEnum.SALE_STAGE), saleStageCodeIn)));
            List<String> fieldList = new ArrayList<>();
            fieldList.add(FieldTypeEnum.DATAID.getAlias());
            List<PaasFormDataEntityExt> esEntities = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_OPPORTUNITY, filter, PaasFormDataEntityExt.class, fieldList);
            Set<Long> ids = new HashSet<>();
            for (PaasFormDataEntityExt esEntity : esEntities) {
                ids.add(esEntity.getDataId());
            }
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("del", 0);
            param.put("idIn", ids);
            opportunityList = opportunityModel.findEntitys(param);
        } catch (Exception e) {
            //es 出错转数据库
            opportunityList = opportunityModel.getOpportunityByEstimateEndTime(corpid, startEstimateEndTime, endEstimateEndTime);
        }
        pushTime += 28800;
        for (OpportunityEntityExt opportunity : opportunityList) {
            JSONObject opportunityDataObject = opportunity.getData();
            if (opportunityDataObject != null) {
                String opportuntiyName = opportunityDataObject.getString(SalesOpportunityEnum.NAME.getAttr());
                Integer estimateEndTime = opportunityDataObject.getInteger(SalesOpportunityEnum.ESTIMATE_END_TIME.getAttr());

                String content = String.format(I18nMessageUtil.getMessage(OpportunityPushConstant.OPPORTUNITY_EXPIRE), opportuntiyName, -DateTimeUtil.betweenDays(businessTime, DateUtil.getTodayInt()));
                String endTimeStr = DateUtil.getDateString(estimateEndTime);

                List<String> pushUserIdList = new ArrayList<>();
                List<String> mainUserIdList = new ArrayList<>();
                //type处理
                String pushObjectStr = pushSetEntity.getPushObject();
                JSONObject pushObject = JsonHelperUtil.parseObject(pushObjectStr);
                String typeString = pushObject.getString("type");
                JSONArray typeJsonArray = JsonHelperUtil.parseArray(typeString);
                for (Object object : typeJsonArray) {
                    JSONObject jsonObject = (JSONObject) object;
                    Integer enable = jsonObject.getInteger("enable");
                    if (Objects.equals(enable, 1)) {
                        String alias = jsonObject.getString("alias");
                        if (Objects.equals(alias, PushObjectTypeEnum.MAINUSER.getAlias())) {
                            pushUserIdList.addAll(opportunityUserModel.getOpportunityUserIdList(corpid, opportunity.getId(), 1));
                            mainUserIdList.addAll(pushUserIdList);
                        }
                        if (Objects.equals(alias, PushObjectTypeEnum.COLLABORATOR.getAlias())) {
                            pushUserIdList.addAll(opportunityUserModel.getOpportunityUserIdList(corpid, opportunity.getId(), 0));
                        }
                    }
                }

                if (mainUserIdList != null && mainUserIdList.size() > 0) {
                    Map<String, Object> paramUser = new HashMap<>(16);
                    paramUser.put("corpid", corpid);
                    paramUser.put("del", 0);
                    paramUser.put("userIdIn", mainUserIdList);
                    List<UserEntity> userEntityList = userModel.findEntitys(paramUser);
                    for (UserEntity userEntity : userEntityList) {
                        pushUserIdList = pushHelper.getPushUserIdList(userEntity, pushObjectStr, pushUserIdList, null);
                    }
                }

                UserEntity userEntity = new UserEntity();
                userEntity.setCorpid(corpid);
                userEntity.setDepartment("[]");
                pushUserIdList = pushHelper.getPushUserIdList(userEntity, pushObjectStr, pushUserIdList, null);

                MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO();
                messageRabbitMqDTO.setCorpid(corpid);
                messageRabbitMqDTO.setUserIds(pushUserIdList);
                messageRabbitMqDTO.setRefIds(Collections.singletonList(opportunity.getId()));
                messageRabbitMqDTO.setRemind(0);
                messageRabbitMqDTO.setPushTime(pushTime);
                messageRabbitMqDTO.setTitle(I18nMessageUtil.getMessage(OpportunityPushConstant.OPPORTUNITY_EXPIRE_TITLE));
                messageRabbitMqDTO.setContent(content);
                OA.Body.Form form = new OA.Body.Form();
                form.setKey(I18nMessageUtil.getMessage(I18nStringConstant.EXPECTED_END_TIME));
                form.setValue(endTimeStr);
                messageRabbitMqDTO.setForm(Collections.singletonList(form));

                PushRefTypePojo.Options options = new PushRefTypePojo.Options();
                options.setAppId(opportunity.getAppId());
                options.setMenuId(opportunity.getMenuId());
                options.setFormId(opportunity.getFormId());
                options.setDataId(opportunity.getId());
                options.setBusinessType(XbbRefTypeEnum.SALES_OPPORTUNITY.getCode());
                options.setSaasMark(SaasMarkEnum.SAAS.getCode());
                messageRabbitMqDTO.setOptions(options);

                try {
                    insertPushData(messageRabbitMqDTO, PushTypeEnum.OPPORTUNITY_EXPIRE_PUSH);
                } catch (XbbException e) {
                    LOG.warn("MessageServiceImpl.opportunityBusinessToPush insertPushData出错,corpid= " + corpid + ", message= " + messageRabbitMqDTO.toString(), e);
                }
            }
        }


/*        for (OpportunityEntityExt opportunity : opportunityList) {
            JSONObject opportunityDataObject = JsonHelperUtil.parseObject(opportunity.getData());
            String opportuntiyName = opportunityDataObject.getString(SalesOpportunityEnum.NAME.getAttr());
            Integer estimateEndTime = opportunityDataObject.getInteger(SalesOpportunityEnum.ESTIMATE_END_TIME.getAttr());

            String content = String.format(OpportunityPushConstant.OPPORTUNITY_EXPIRE, opportuntiyName, -DateUtil.betweenDays(businessTime, DateUtil.getTodayInt()));
            String endTimeStr = DateUtil.getDateString(estimateEndTime);
            JSONObject msgObject = new JSONObject();
            msgObject.put("预计结束时间", endTimeStr);

            List<String> pushUserIdList = new ArrayList<>();
            List<String> mainUserIdList = new ArrayList<>();
            //type处理
            String pushObjectStr = pushSetEntity.getPushObject();
            JSONObject pushObject = JsonHelperUtil.parseObject(pushObjectStr);
            String typeString = pushObject.getString("type");
            JSONArray typeJsonArray = JsonHelperUtil.parseArray(typeString);
            for (Object object : typeJsonArray) {
                JSONObject jsonObject = (JSONObject) object;
                Integer enable = jsonObject.getInteger("enable");
                if (Objects.equals(enable, 1)) {
                    String alias = jsonObject.getString("alias");
                    if (Objects.equals(alias, PushObjectTypeEnum.MAINUSER.getAlias())) {
                        pushUserIdList.addAll(opportunityUserModel.getOpportunityUserIdList(corpid, opportunity.getId(), 1));
                        mainUserIdList.addAll(pushUserIdList);
                    }
                    if (Objects.equals(alias, PushObjectTypeEnum.COLLABORATOR.getAlias())) {
                        pushUserIdList.addAll(opportunityUserModel.getOpportunityUserIdList(corpid, opportunity.getId(), 0));
                    }
                }
            }

            if (mainUserIdList != null && mainUserIdList.size() > 0) {
                Map<String, Object> paramUser = new HashMap<>(16);
                paramUser.put("corpid", corpid);
                paramUser.put("del", 0);
                paramUser.put("userIdIn", mainUserIdList);
                List<UserEntity> userEntityList = userModel.findEntitys(paramUser);
                for (UserEntity userEntity : userEntityList) {
                    pushUserIdList = pushService.getPushUserIdList(userEntity, pushObjectStr, pushUserIdList, null);
                }
            }

            UserEntity userEntity = new UserEntity();
            userEntity.setCorpid(corpid);
            userEntity.setDepartment("[]");
            pushUserIdList = pushService.getPushUserIdList(userEntity, pushObjectStr, pushUserIdList, null);

            pushService.delayedPush(corpid, pushUserIdList, OpportunityPushConstant.OPPORTUNITY_EXPIRE_TITLE, content, RefEntityEnum.SALES_OPPORTUNITY_ENTITY, opportunity.getId(), PushTypeEnum.OPPORTUNITY_EXPIRE_PUSH, pushTime, msgObject);
        }*/

    }

    @Override
    public void quotationBusinessToPush(String corpid) {
        // 如果今天的到期机会已经生成了，则不再重复生成
        if (pushCheck(corpid, PushTypeEnum.QUOTATION_REMIND)) {
            LOG.info("quotationBusinessToPush 报价单到期提醒数据已生成，　corpid=" + corpid);
            return;
        }
        QuotationRemindPushSet quotationRemindPushSet = new QuotationRemindPushSet();
        PushSetEntity pushSetEntity = quotationRemindPushSet.getPushSet(corpid, PushTypeEnum.QUOTATION_REMIND.getSubCode(), pushSetModel);
        if (Objects.equals(pushSetEntity.getEnable(), 0)) {
            return;
        }
        JSONObject pushTimeObject = JSONObject.parseObject(pushSetEntity.getPushTime());
        Integer timeType = pushTimeObject.getInteger("timeType");
        Integer period = pushTimeObject.getInteger("period");

        Long pushTime = DateTimeUtil.getTodayInt();
        Long businessTime = pushTime;
        if (Objects.equals(PushTimeTypeEnum.ADVANCE.getCode(), timeType)) {
            businessTime = pushTime + period;
        }

        Long startEstimateEndTime = DateTimeUtil.getTodayInt(businessTime);
        Long endEstimateEndTime = startEstimateEndTime + 86400;
        List<QuotationEntityExt> quotationList = new ArrayList<>();
        try {
            BoolQueryBuilder filter = boolQuery()
                    .filter(termQuery("corpid.keyword", corpid))
                    .filter(termQuery("del", 0))
                    .filter(termsQuery("flowStatus", Arrays.asList(FlowStatusEnum.NOT_NEED_APPROVAL.getType(), FlowStatusEnum.PASS.getType())))
                    .filter(rangeQuery("data." + QuotationEnum.EFFECTIVE_TIME.getAttr()).gte(startEstimateEndTime).lt(endEstimateEndTime));
            List<String> fieldList = new ArrayList<>();
            fieldList.add(FieldTypeEnum.DATAID.getAlias());
            List<PaasFormDataEntityExt> esEntities = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_QUOTATION, filter, PaasFormDataEntityExt.class, fieldList);
            Set<Long> ids = new HashSet<>();
            for (PaasFormDataEntityExt esEntity : esEntities) {
                ids.add(esEntity.getDataId());
            }
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("del", 0);
            param.put("idIn", ids);
            quotationList = quotationModel.findEntitys(param);
        } catch (Exception e) {
            //es 出错转数据库
            quotationList = quotationModel.getQuotationByDeadlineTime(corpid, startEstimateEndTime, endEstimateEndTime);
        }

        pushTime += 28800;
        for (QuotationEntityExt quotation : quotationList) {
            JSONObject quotationDataObject = quotation.getData();
            if (quotationDataObject != null) {
                String customerName = quotationDataObject.getString(QuotationEnum.CUSTOMER_NAME.getAttr());
                String quotationName = quotationDataObject.getString(QuotationEnum.NAME.getAttr());
                Integer estimateEndTime = quotationDataObject.getInteger(QuotationEnum.EFFECTIVE_TIME.getAttr());

                String content = String.format(I18nMessageUtil.getMessage(QuotationPushConstant.QUOTATAION_REMIND_CONTENT), quotationName, -DateTimeUtil.betweenDays(businessTime, DateUtil.getTodayInt()));
                String endTimeStr = DateUtil.getDateString(estimateEndTime);

                List<String> pushUserIdList = new ArrayList<>();
                List<String> mainUserIdList = new ArrayList<>();
                //type处理
                String pushObjectStr = pushSetEntity.getPushObject();
                JSONObject pushObject = JsonHelperUtil.parseObject(pushObjectStr);
                String typeString = pushObject.getString("type");
                JSONArray typeJsonArray = JsonHelperUtil.parseArray(typeString);
                for (Object object : typeJsonArray) {
                    JSONObject jsonObject = (JSONObject) object;
                    Integer enable = jsonObject.getInteger("enable");
                    if (Objects.equals(enable, 1)) {
                        String alias = jsonObject.getString("alias");
                        if (Objects.equals(alias, PushObjectTypeEnum.MAINUSER.getAlias())) {
                            pushUserIdList.addAll(quotationUserModel.getQuotationUserIdList(corpid, quotation.getId(), 1));
                            mainUserIdList.addAll(pushUserIdList);
                        }
                        if (Objects.equals(alias, PushObjectTypeEnum.COLLABORATOR.getAlias())) {
                            pushUserIdList.addAll(quotationUserModel.getQuotationUserIdList(corpid, quotation.getId(), 0));
                        }
                    }
                }

                if (mainUserIdList != null && mainUserIdList.size() > 0) {
                    Map<String, Object> paramUser = new HashMap<>(16);
                    paramUser.put("corpid", corpid);
                    paramUser.put("del", 0);
                    paramUser.put("userIdIn", mainUserIdList);
                    List<UserEntity> userEntityList = userModel.findEntitys(paramUser);
                    for (UserEntity userEntity : userEntityList) {
                        pushUserIdList = pushHelper.getPushUserIdList(userEntity, pushObjectStr, pushUserIdList, null);
                    }
                }

                UserEntity userEntity = new UserEntity();
                userEntity.setCorpid(corpid);
                userEntity.setDepartment("[]");
                pushUserIdList = pushHelper.getPushUserIdList(userEntity, pushObjectStr, pushUserIdList, null);

                MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO();
                messageRabbitMqDTO.setCorpid(corpid);
                messageRabbitMqDTO.setUserIds(pushUserIdList);
                messageRabbitMqDTO.setRefIds(Collections.singletonList(quotation.getId()));
                messageRabbitMqDTO.setRemind(0);
                messageRabbitMqDTO.setPushTime(pushTime);
                messageRabbitMqDTO.setTitle(I18nMessageUtil.getMessage(QuotationPushConstant.QUOTATAION_REMIND_TITLE));
                messageRabbitMqDTO.setContent(content);
                OA.Body.Form form = new OA.Body.Form();
                form.setKey(I18nMessageUtil.getMessage(I18nStringConstant.EXPECTED_END_TIME));
                form.setValue(endTimeStr);
                messageRabbitMqDTO.setForm(Collections.singletonList(form));

                PushRefTypePojo.Options options = new PushRefTypePojo.Options();
                options.setAppId(quotation.getAppId());
                options.setMenuId(quotation.getMenuId());
                options.setFormId(quotation.getFormId());
                options.setDataId(quotation.getId());
                options.setBusinessType(XbbRefTypeEnum.QUOTATION.getCode());
                options.setSaasMark(SaasMarkEnum.SAAS.getCode());
                messageRabbitMqDTO.setOptions(options);

                try {
                    insertPushData(messageRabbitMqDTO, PushTypeEnum.QUOTATION_REMIND);
                } catch (XbbException e) {
                    LOG.error("MessageServiceImpl.opportunityBusinessToPush insertPushData出错,corpid= " + corpid + ", message= " + messageRabbitMqDTO.toString(), e);
                }
            }
        }

    }

    @Override
    public void workReportBusinessToPush(String corpid,Long todayInt,Long todayEndInt) {
        WorkReportRemindPushSet workReportRemindPushSet = new WorkReportRemindPushSet();
        PushSetEntity remindPushSetEntity = workReportRemindPushSet.getPushSet(corpid, PushTypeEnum.WORK_REPORT_REMIND_PUSH.getSubCode(), pushSetModel);

        WorkReportOverduePushSet workReportOverduePushSet = new WorkReportOverduePushSet();
        PushSetEntity overduePushSetEntity = workReportOverduePushSet.getPushSet(corpid, PushTypeEnum.WORK_REPORT_OVERDUE_PUSH.getSubCode(), pushSetModel);

        boolean remindPushEnable = Objects.nonNull(remindPushSetEntity) && Objects.equals(remindPushSetEntity.getEnable(), 1);
        boolean overduePushEnable = Objects.nonNull(overduePushSetEntity) && Objects.equals(overduePushSetEntity.getEnable(), 1);
        LOG.info("remindPushEnable: {},overduePushEnable: {}",remindPushEnable,overduePushEnable);
        if (!remindPushEnable && !overduePushEnable) {
            return;
        }

        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.CORPID, corpid);
        param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        List<WorkReportSetEntity> workReportSetEntityList = workReportSetModel.findEntitys(param);

        if (CollectionsUtil.isEmpty(workReportSetEntityList)) {
            LOG.info("工作报告提醒消息推送获取工作报告设置为空，corpid = " + corpid);
            return;
        }

        Map<Integer, WorkReportSetEntity> workReportSetEntityMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);

        for (WorkReportSetEntity setEntity : workReportSetEntityList) {
            if (Objects.equals(setEntity.getEnable(), 0)) {
                continue;
            }
            WorkReportSetEntity workReportSetEntity = workReportSetEntityMap.get(setEntity.getType());
            if (Objects.isNull(workReportSetEntity)) {
                workReportSetEntityMap.put(setEntity.getType(), setEntity);
            }
        }
        List<PaasFormExplainEntity> workReportExplain = null;
        try {
            workReportExplain = paasFormExplainModel.getListForUpdateProduct(corpid, Arrays.asList(XbbRefTypeEnum.WORKREPORT_DAILY.getCode(), XbbRefTypeEnum.WORKREPORT_WEEKLY.getCode(), XbbRefTypeEnum.WORKREPORT_MONTHLY.getCode()));
        } catch (XbbException e) {
            LOG.info("工作报告提醒消息推送获取工作报告解释为空，corpid = " + corpid);
            return;
        }
        if (CollectionsUtil.isEmpty(workReportExplain)) {
            LOG.info("工作报告提醒消息推送获取工作报告解释为空，corpid = " + corpid);
            return;
        }
        Long appId = workReportExplain.get(0).getAppId();
        Long menuId = workReportExplain.get(0).getMenuId();
        // 有满足的工作报告时，还要查询此家公司今天有没有生成消息，已经生成则不生成
        List<Long> idList = pushModel.getAlreadyProduceId(corpid,todayInt,todayEndInt,PushTypeEnum.WORK_REPORT_REMIND_PUSH.getSubCode(),XbbRefTypeEnum.WORK_REPORT.getCode());
        if (CollectionsUtil.isNotEmpty(idList)){
            return;
        }
        // 查询此家公司今天有没有生成消息，已经生成则不生成
        idList = pushModel.getAlreadyProduceId(corpid,todayInt,todayEndInt,PushTypeEnum.WORK_REPORT_OVERDUE_PUSH.getSubCode(),XbbRefTypeEnum.WORK_REPORT.getCode());
        if (CollectionsUtil.isNotEmpty(idList)){
            return;
        }
        for (Map.Entry<Integer, WorkReportSetEntity> entry : workReportSetEntityMap.entrySet()) {
            WorkReportSetEntity workReportSetEntity = entry.getValue();
            Integer type = entry.getKey();

            if (remindPushEnable) {
                setWorkReportRemindPush(corpid, type, remindPushSetEntity, workReportSetEntity, appId, menuId);
            }
            if (overduePushEnable) {
                setWorkReportOverduePush(corpid, type, overduePushSetEntity, workReportSetEntity, appId, menuId);
            }
        }

    }

    @Override
    public void businessToPush(MessageSaveAllTargetDataDTO messageSaveAllTargetDataDTO) throws XbbException{

        String key = messageSaveAllTargetDataDTO.getKey();
        if (!Objects.equals(key, BasicConstant.TASK_SECRET_KEY)) {
            LOG.error("销售简报统计数据入库 密码错误，停止定时任务！");
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100066);
        }

        Integer pageSize = 5000;
        Map<String, Object> param = new HashMap<>(16);
        param.put("del", 0);
        //正常使用
        param.put("status", 1);
        //开启了推送
        param.put("isPushMessage", 1);
        param.put("orderByStr", "add_time asc, corpid asc");
        param.put("columns", "corpid");
        Integer companyCount = companyModel.getEntitysCount(param);
        Integer threadNum = companyCount / pageSize + 1;
        for (int i = 1; i < threadNum + 1; i++) {
            Integer start = (i - 1) * pageSize;
            Integer pageNum = i * pageSize;

            param.put("start", start);
            param.put("pageNum", pageNum);
            List<CompanyEntity> companys = companyModel.findEntitys(param);
            for (CompanyEntity company : companys) {
                String corpid = company.getCorpid();

                customerBusinessToPush(corpid);
                contractBusinessToPush(corpid);
                opportunityBusinessToPush(corpid);
                quotationBusinessToPush(corpid);
            }
        }
    }

    @Override
    public void saveAllTargetData(MessageSaveAllTargetDataDTO messageSaveAllTargetDataDTO) throws XbbException{
        LOG.info("------------------------- 销售简报统计数据入库 -> 定时任务 开始执行 --------------------------");
        LOG.info("========================= 销售简报统计数据入库 定时任务执行开始时间：" + DateUtil.getInt() + " ==========================");
        if (mTargetDataExecutor == null || mTargetDataExecutor.isShutdown()) {
            mTargetDataExecutor = Executors.newFixedThreadPool(8, new NamedThreadFactory("xbb-timedTask-targetData-Executor"));
        }
        String oneCorpid = messageSaveAllTargetDataDTO.getOneCorpid();
        String key = messageSaveAllTargetDataDTO.getKey();
        if (!Objects.equals(key, BasicConstant.TASK_SECRET_KEY)) {
            LOG.error("销售简报统计数据入库 密码错误，停止定时任务！");
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100066);
        }
        if (StringUtil.isNotEmpty(oneCorpid)) {
            Map<String, Object> param = new HashMap<>(16);
            param.put("corpid", oneCorpid);
            param.put("del", 0);
            param.put("status", 1);
            param.put("isPushMessage", 1);
            //获取所有公司
            List<CompanyEntity> companys = companyModel.findEntitys(param);
            if (companys == null || companys.size() == 0) {
//                return ReturnHelper.setReturn(request, response, modelMap, 0, "公司不存在，或该公司未开启推送消息开关", "/front/error");
            }
            //刷单公司数据，则排重（防止该公司数据已经存在，重复生成）
            submitTimedTask(new ReportTargetDataThread(messageSaveAllTargetDataDTO, companys, true));
        } else {
            //每个线程的最大公司处理数
            Integer pageSize = 5000;
            Map<String, Object> param = new HashMap<>();
            param.put("del", 0);
            param.put("status", 1);
            param.put("isPushMessage", 1);
            //获取所有公司
            Integer companyCount = companyModel.getEntitysCount(param);
            //线程数，可由pageSize控制
            Integer threadNum = companyCount / pageSize + 1;
            for (int i = 1; i < threadNum + 1; i++) {
                submitTimedTask(new ReportTargetDataThread(messageSaveAllTargetDataDTO, (i - 1) * pageSize, pageSize));
            }
        }
        LOG.info("========================= 销售简报统计数据入库 定时任务执行结束时间：" + DateUtil.getInt() + " ==========================");
        LOG.info("------------------------- 销售简报统计数据入库 -> 定时任务 顺利结束 --------------------------");
    }
    /**
     * 将线程丢入线程池并将线程池异常添加到 resultList 中
     *
     * @param timedTask 退回公海池定时任务
     *
     * @author 章华隽
     * 创建时间： 2017/8/23 上午12:00
     * 修改时间：
     * @version
     * @since 3.12
     */
    private void submitTimedTask(ReportTargetDataThread timedTask) {
        timedTask.setSalesReportFeignClient(salesReportFeignClient);
        timedTask.setCompanyModel(companyModel);
        timedTask.setUserModel(userModel);
        timedTask.setCustomerModel(customerModel);
        timedTask.setTargetLogModel(targetLogModel);
        timedTask.setCompanyConfigModel(companyConfigModel);

        ThreadPoolHelper.getInstance().submitExecutorRunnable(mTargetDataExecutor, timedTask);
    }

    @Override
    public void saveAllPushData(MessageSaveAllTargetDataDTO messageSaveAllTargetDataDTO) throws XbbException{
        LOG.info("------------------------- 销售简报，未回款提醒，逾期回款提醒，未付款提醒，逾期付款提醒推送数据入库 -> 定时任务 开始执行 --------------------------");
        LOG.info("========================= 销售简报，未回款提醒，逾期回款提醒，未付款提醒，逾期付款提醒推送数据入库 定时任务执行开始时间：" + DateUtil.getInt() + " ==========================");
        if (mAllPushExecutor == null || mAllPushExecutor.isShutdown()) {
            mAllPushExecutor = Executors.newFixedThreadPool(8, new NamedThreadFactory("xbb-timedTask-pushData-Executor"));
        }
        String corpid = messageSaveAllTargetDataDTO.getOneCorpid();
        String key = messageSaveAllTargetDataDTO.getKey();
        if (!Objects.equals(key, BasicConstant.TASK_SECRET_KEY)) {
            LOG.error("销售简报统计数据入库 密码错误，停止定时任务！");
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100066);
        }
        if (StringUtil.isNotEmpty(corpid)) {
            Map<String,Object> param = new HashMap<>(16);
            param.put("corpid", corpid);
            param.put("del", 0);
            param.put("status", 1);
            param.put("isPushMessage", 1);
            //获取所有公司
            List<CompanyEntity> companys = companyModel.findEntitys(param);
            if (companys == null || companys.size() == 0) {
//                return ReturnHelper.setReturn(request, response, modelMap, 0, "公司不存在，或该公司未开启推送消息开关", "/front/error");
            }
            //刷单公司数据，则排重（防止该公司数据已经存在，重复生成
            submitTimedTask(new PushDataThread(companys));
        } else {
            // 获取所有公司
            Integer pageSize = 5000;
            Map<String,Object> param = new HashMap<>(16);
            param.put("del", 0);
            param.put("status", 1);
            param.put("isPushMessage", 1);
            Integer companyCount = companyModel.getEntitysCount(param);

            // 线程数，可由pageSize控制
            Integer threadNum = companyCount / pageSize + 1;
            for(int i = 1; i < threadNum + 1; i++){
                submitTimedTask(new PushDataThread((i-1) * pageSize, pageSize));
            }
        }
        LOG.info("========================= 销售简报，未回款提醒，逾期回款提醒，未付款提醒，逾期付款提醒推送数据入库 定时任务执行结束时间：" + DateUtil.getInt() + " ==========================");
        LOG.info("------------------------- 销售简报，未回款提醒，逾期回款提醒，未付款提醒，逾期付款提醒推送数据入库 -> 定时任务 顺利结束 --------------------------");
    }
    /**
     * 将线程丢入线程池并将线程池异常添加到 resultList 中
     *
     * @param timedTask 退回公海池定时任务
     *
     * @author 章华隽
     * 创建时间： 2017/8/23 上午12:00
     * 修改时间：
     * @version
     * @since 3.12
     */
    private void submitTimedTask(PushDataThread timedTask) {
        timedTask.setCompanyModel(companyModel);
        timedTask.setUserModel(userModel);
        timedTask.setPushSetModel(pushSetModel);
        timedTask.setPushModel(pushModel);
        timedTask.setCustomerModel(customerModel);
        timedTask.setPaymentModel(paymentModel);
        timedTask.setContractUserModel(contractUserModel);
        timedTask.setCompanyConfigModel(companyConfigModel);
        timedTask.setTargetLogModel(targetLogModel);
        timedTask.setPushService(pushService);
        timedTask.setProBaseConfig(proBaseConfig);
        timedTask.setMessageService(this);
        timedTask.setPushHelper(pushHelper);
        timedTask.setEsHelper(esHelper);
        timedTask.setPayPlanModel(payPlanModel);
        timedTask.setPurchaseUserModel(purchaseUserModel);
        timedTask.setXbbElasticsearchRestTemplate(xbbElasticsearchRestTemplate);
        timedTask.setIndexTypeModel(indexTypeModel);
        ThreadPoolHelper.getInstance().submitExecutorRunnable(mAllPushExecutor, timedTask);
    }

    @Override
    public void saveExpiredReminder(MessageExpiredReminderDTO messageExpiredReminderDTO) throws XbbException {
        String key = messageExpiredReminderDTO.getKey();
        if (!Objects.equals(key, BasicConstant.TASK_SECRET_KEY)) {
            LOG.error("套餐到期提醒定时消息发送 -> 定时任务 密码错误，停止定时任务！");
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100066);
        }
        LOG.info("------------------------- 套餐到期提醒定时消息发送 -> 定时任务 开始执行 --------------------------");
        LOG.info("========================= 套餐到期提醒定时消息发送 定时任务执行开始时间：" + DateUtil.getInt() + " ==========================");
        if (mExpiredReminderExecutor == null || mExpiredReminderExecutor.isShutdown()) {
            mExpiredReminderExecutor = Executors.newFixedThreadPool(8, new NamedThreadFactory("xbb-timedTask-expiredReminder-Executor"));
        }
        //获取所有公司
        Integer pageSize = 5000;
        Map<String,Object> param = new HashMap<>(16);
        param.put("del", 0);
        param.put("status", 1);
//		param.put("isPushMessage", 1);
        //来源，1:钉钉 2:独立版
        param.put("source", 1);
        Integer companyCount = companyModel.getEntitysCount(param);
        //线程数，可由pageSize控制
        Integer threadNum = companyCount/pageSize+1;
        for(int i = 1; i < threadNum + 1; i++) {
            submitTimedTask(new ExpiredReminderThread((i-1) * pageSize, pageSize));
        }
        LOG.info("========================= 套餐到期提醒定时消息发送 定时任务执行结束时间：" + DateUtil.getInt() + " ==========================");
        LOG.info("------------------------- 套餐到期提醒定时消息发送 -> 定时任务 顺利结束 --------------------------");
    }
    /**
     * 将线程丢入线程池并将线程池异常添加到 resultList 中
     *
     * @param timedTask 退回公海池定时任务
     *
     * @author 章华隽
     * 创建时间： 2017/8/23 上午12:00
     * 修改时间：
     * @since 3.12
     */

    private void submitTimedTask(ExpiredReminderThread timedTask) {
        timedTask.setCompanyModel(companyModel);
        timedTask.setFeeCompanyModel(feeCompanyModel);
        timedTask.setUserModel(userModel);
        timedTask.setMessageService(this);
        ThreadPoolHelper.getInstance().submitExecutorRunnable(mExpiredReminderExecutor, timedTask);
    }

//    @Override
    public void dingtalkOAMessagePush(String corpid, AbstractMessage message, List<String> userIdList) throws XbbException {
        String accessToken;
        String agentId;
        try {
            accessToken = authHelper.getAccessToken(corpid);
            agentId = authHelper.getAgentId(corpid, Env.DING_XBB_APP_ID);
        } catch(Exception e) {
            LOG.error("获取accessToken或agentId失败", e);
            throw new XbbException(MessageErrorCodeEnum.API_ERROR_380002);
        }
        for (String userId : userIdList) {
            LightAppMessageDelivery lightAppMessageDelivery = new LightAppMessageDelivery(userId, "", agentId);
//            lightAppMessageDelivery.withMessage(message);
            try {
                MessageHelper.send(accessToken, lightAppMessageDelivery);
            } catch (OApiException e) {
                LOG.error("推送失败,钉钉接口错误", e);
//                throw new XbbException(ErrorCodeEnum.API_ERROR_380004);
            } catch (Exception e) {
                LOG.error("MessageHelper.send() 错误，非钉钉接口错误，可能是socket错误:",e);
//                throw new XbbException(ErrorCodeEnum.API_ERROR_380003);
            }
        }
    }

    @Async(value = "messageThreadPool")
    @Override
    public void delayPushDingtalkOAMessage(MessageRabbitMqDTO messageRabbitMqDTO, PushTypeEnum pushTypeEnum) throws XbbException {
        String corpid = messageRabbitMqDTO.getCorpid();
        List<String> userIds = messageRabbitMqDTO.getUserIds();
        List<Long> refIds = messageRabbitMqDTO.getRefIds();
        if (StringUtil.isEmpty(corpid)) {
            LOG.warn("com.xbongbong.pro.message.service.impl.MessageServiceImpl.delayPushDingtalkOAMessage warn,  MessageRabbitMqDTO = " + JSON.toJSONString(messageRabbitMqDTO), new XbbException(MessageErrorCodeEnum.API_ERROR_380007, MessageErrorCodeEnum.API_ERROR_380007.getMsg() + pushTypeEnum));
            return;
//            throw new XbbException(MessageErrorCodeEnum.API_ERROR_380007, MessageErrorCodeEnum.API_ERROR_380007.getMsg() + pushTypeEnum);
        }
        if (userIds == null || userIds.size() == 0) {
            LOG.warn("com.xbongbong.pro.message.service.impl.MessageServiceImpl.delayPushDingtalkOAMessage warn,  MessageRabbitMqDTO = " + JSON.toJSONString(messageRabbitMqDTO), new XbbException(MessageErrorCodeEnum.API_ERROR_380005, MessageErrorCodeEnum.API_ERROR_380005.getMsg() + pushTypeEnum));
            return;
//            throw new XbbException(MessageErrorCodeEnum.API_ERROR_380005, MessageErrorCodeEnum.API_ERROR_380005.getMsg() + pushTypeEnum);
        }
        if (userIds.size() > 100) {
            LOG.warn("com.xbongbong.pro.message.service.impl.MessageServiceImpl.delayPushDingtalkOAMessage warn,  MessageRabbitMqDTO = " + JSON.toJSONString(messageRabbitMqDTO), new XbbException(MessageErrorCodeEnum.API_ERROR_380008, MessageErrorCodeEnum.API_ERROR_380008.getMsg() + pushTypeEnum));
            return;
//            throw new XbbException(MessageErrorCodeEnum.API_ERROR_380008, MessageErrorCodeEnum.API_ERROR_380008.getMsg() + pushTypeEnum);
        }
        if (refIds == null || refIds.size() == 0) {
            LOG.warn("com.xbongbong.pro.message.service.impl.MessageServiceImpl.delayPushDingtalkOAMessage warn,  MessageRabbitMqDTO = " + JSON.toJSONString(messageRabbitMqDTO), new XbbException(MessageErrorCodeEnum.API_ERROR_380006, MessageErrorCodeEnum.API_ERROR_380006.getMsg() + pushTypeEnum));
            return;
//            throw new XbbException(MessageErrorCodeEnum.API_ERROR_380006, MessageErrorCodeEnum.API_ERROR_380006.getMsg() + pushTypeEnum);
        }

        Integer isRemind = messageRabbitMqDTO.getRemind();
        Long pushTime = messageRabbitMqDTO.getPushTime();
        String title = messageRabbitMqDTO.getTitle();
        String content = messageRabbitMqDTO.getContent();

        List<OA.Body.Form> formList = messageRabbitMqDTO.getForm();

        PushRefTypePojo.Options options = messageRabbitMqDTO.getOptions();

        boolean openWorkFlow = commonHelp.isOpenWorkFlow(corpid);

        OA oaMessage = formatOaMessage(pushTypeEnum, title, content, formList, options, corpid, false, openWorkFlow);

        String type = formatRefType(pushTypeEnum, options, false, openWorkFlow);

        Long now = DateTimeUtil.getInt();
        //以下备注的都是弃用的  @date 2019/2/26 19:37  @author 魏荣杰
        PushEntity pushEntity = new PushEntity();
        pushEntity.setCorpid(corpid);
        pushEntity.setRefEntity(pushTypeEnum.getCode());
        // TODO: 2019/3/1 refid 待优化，目前用于跟进提醒
        pushEntity.setRefId(refIds.get(0));
        pushEntity.setRefArray(JSONObject.toJSONString(refIds));

        pushEntity.setRefType(type);
        pushEntity.setType(pushTypeEnum.getCode());
        pushEntity.setSubType(pushTypeEnum.getSubCode());
        pushEntity.setPushObject(JSONObject.toJSONString(userIds));
        pushEntity.setMsg(JSONObject.toJSONString(oaMessage));
        pushEntity.setPushTime(pushTime);
        pushEntity.setIsPush(0);
        pushEntity.setIsRemind(isRemind);
        pushEntity.setAddTime(now);
        pushEntity.setUpdateTime(now);

        if (Objects.equals(isRemind, 1)) {
            //如果是提醒的消息，直接保存不推送，需要在用户设置的时间推送，走轮询
            pushService.save(pushEntity);
        } else {
            //推送钉钉OA消息
            try {
                //旧方法
//                dingtalkOAMessagePush(corpid, oaMessage, userIds);
                String userIdsStr = null;

                List<UserEntity> byUserIdIn = userModel.getByUserIdIn(corpid, userIds, true);
                for (UserEntity userEntity : byUserIdIn) {
                    if (userIdsStr == null) {
                        userIdsStr = userEntity.getUserId();
                    } else {
                        userIdsStr += "," + userEntity.getUserId();
                    }
                }
                if (userIdsStr != null && userIdsStr.length() > 0) {

                    TemplateMessage templateMessage = templateMessageTransferHelper.transferToTemplateMessage(oaMessage);

                    CorpConversationHelper.SendByTemplateResponse sendResponse = messageNewService.dingtalkWorkMessageByTemplatePushToUserAndDept(corpid, templateMessage, userIdsStr, null);
                    if (sendResponse != null) {
                        pushEntity.setTaskId(sendResponse.getTaskId());
                    }
                    //推送成功is_push设置为1
                    pushEntity.setIsPush(1);
                } else {
                    //推送对象没有直接标记无效消息，用del=2标记
                    pushEntity.setDel(2);
                }
                //push,push_link表入库
                pushService.save(pushEntity);
            } catch (XbbException e) {
                pushService.save(pushEntity);
                throw e;
            } catch (Exception e) {
                pushService.save(pushEntity);
                throw e;
            }
        }

    }
    /**
     * Description: 封装消息refType字段用于系统内跳转
     * @param pushTypeEnum 推送枚举
     * @param options 参数
     * @param openWorkFlow
     * @return java.lang.String
     * @throws XbbException XbbException
     * @author 魏荣杰
     * @date 2019/4/8 11:25
     * @since v1.0
     */
    private String formatRefType(PushTypeEnum pushTypeEnum, PushRefTypePojo.Options options, boolean isCreator, boolean openWorkFlow) throws XbbException {
        PushRefTypePojo pushRefTypePojo = new PushRefTypePojo();
        Map<String, Object> optionMap;
        switch (pushTypeEnum) {
            //客户
            case CUSTOMER_PUSH:
            case CUSTOMER_ADD_PUSH:
            case CUSTOMER_CHANGE_PUSH:
            case CUSTOMER_TEAM_ADD_DEL_MAIN:
            case CUSTOMER_TEAM_ADD_DEL_SYNERGETIC:
            case CUSTOMER_STAGE:
            case CUSTOMER_REMIND:
            // 经销商档案
            case DISTRIBUTOR_PUSH:
            case DISTRIBUTOR_ADD_PUSH:
            case DISTRIBUTOR_TEAM_ADD_DEL_MAIN:
            case DISTRIBUTOR_TEAM_ADD_DEL_SYNERGETIC:
            //联系人
            case CONTACT_PUSH:
            case CONTACT_NEW:
            //经销商联系人
            case DISTRIBUTOR_CONTACT_PUSH:
            case DISTRIBUTOR_CONTACT_ADD_PUSH:
            //机会
            case OPPORTUNITY_PUSH:
            case OPPORTUNITY_ADD_PUSH:
            case OPPORTUNITY_CHANGE_PUSH:
            case OPPORTUNITY_EXPIRE_PUSH:
            case OPPORTUNITY_TEAM_ADD_DEL_MAIN_PUSH:
            case OPPORTUNITY_TEAM_ADD_DEL_SYNERGETIC_PUSH:
            case OPPORTUNITY_STAGE_PUSH:
            //访客计划
            case COMMUNICATE_PLAN_PUSH:
            case COMMUNICATE_PLAN_ADD_PUSH:
            //合同
            case CONTRACT_PUSH:
            case CONTRACT_ADD_PUSH:
            case CONTRACT_CHANGE_PUSH:
            case CONTRACT_TEAM_ADD_DEL_MAIN_PUSH:
            case CONTRACT_TEAM_ADD_DEL_SYNERGETIC_PUSH:
            case CONTRACT_REMIND:
            // 订货单
            case ORDER_PUSH:
            case ORDER_ADD_PUSH:
            case ORDER_CHANGE_PUSH:
            case ORDER_TEAM_ADD_DEL_MAIN_PUSH:
            case ORDER_TEAM_ADD_DEL_SYNERGETIC_PUSH:
                //应收款&回款单
            case PAYMENT_PLAN_ADD:
            case PAYMENT_SHEET_ADD:
            case PAYMENT_SHEET_RED_ADD:
            case PAYMENT_SHEET_BAD_ADD:
            case PAYMENT_SHEET_PREPAYMENT_ADD:
            case PAYMENT_SHEET_RED_PREPAYMENT_ADD:
                //付款计划&付款单
            case PAY_PLAN_ADD:
            case PAY_SHEET_ADD:
            case PAY_SHEET_RED_ADD:
            case PAY_SHEET_BAD_ADD:
            case PAY_SHEET_PREPAY_ADD:
            case PAY_SHEET_RED_PREPAY_ADD:
                // 对账单
            case STATEMENT_GENERATE_PUSH:
            case STATEMENT_QUESTION_FEEDBACK_PUSH:
            case STATEMENT_REMIND_CONFIRM_PUSH:
            case STATEMENT_VALET_CONFIRM_PUSH:
            case STATEMENT_REGENERATE_PUSH:
            case CREDIT_FIXED_LIMIT_CHANGE_PUSH:
            //发票
            case INVOICE_PUSH:
            case INVOICE_ADD_PUSH:
            case INVOICE_DEL_PUSH:
            case INVOICE_REDUCTION:
            case INVOICE_INVALIDATION:
            case INVOICE_RED_ADD_PUSH:
                //发票
            case PURCHASE_INVOICE_PUSH:
            case PURCHASE_INVOICE_ADD_PUSH:
            case PURCHASE_INVOICE_DEL_PUSH:
            case PURCHASE_INVOICE_REDUCTION:
            case PURCHASE_INVOICE_INVALIDATION:
            case PURCHASE_INVOICE_RED_ADD_PUSH:
            //采购合同
            case PURCHASE_PUSH:
            case WAIT_PURCHASE_PUSH:
            case PURCHASE_SUCCESS_PUSH:
            case PURCHASE_TEAM_ADD_DEL_MAIN_PUSH:
            case PURCHASE_TEAM_ADD_DEL_SYNERGETIC_PUSH:
            //入库单
            case INSTOCK_PUSH:
            case WAIT_INSTOCK_PUSH:
            case INSTOCK_SUCCESS_PUSH:
            //出库单
            case OUTSTOCK_PUSH:
            case WAIT_OUTSTOCK_PUSH:
            case OUTSTOCK_SUCCESS_PUSH:
            //供应商
            case SUPPLIER_PUSH:
            case SUPPLIER_ADD_PUSH:
            case SUPPLIER_TEAM_ADD_DEL_MAIN_PUSH:
            case SUPPLIER_TEAM_ADD_DEL_SYNERGETIC_PUSH:
            //bom
            case BOMBILL_PUSH:
            case BOMBILL_TEAM_ADD_DEL_MAIN_PUSH:
            case BOMBILL_TEAM_ADD_DEL_SYNERGETIC_PUSH:
            //生产单
            case PRODUCTION_ORDER_PUSH:
            case PRODUCTION_ORDER_TEAM_ADD_DEL_MAIN_PUSH:
            case PRODUCTION_ORDER_TEAM_ADD_DEL_SYNERGETIC_PUSH:
            //退货退款
            /*case REFUND_PUSH:
            case REFUND_ADD_PUSH:
            case REFUND_ADD_WITH_PRODUCT_PUSH:
            case REFUND_ADD_WITHOUT_PRODUCT_PUSH:*/
            //采购退货单
            case RETURNED_PURCHASE_PUSH:
            //报价单
            case QUOTATION_PUSH:
            case QUOTATION_ADD_PUSH:
            case QUOTATION_CHANGE_PUSH:
            case QUOTATION_STATUS_PUSH:
            case QUOTATION_TEAM_ADD_DEL_MAIN_PUSH:
            case QUOTATION_TEAM_ADD_DEL_SYNERGETIC_PUSH:
            case QUOTATION_REMIND:
            //工单
            case WORKORDER_PUSH:
            case WORKORDER_DEL_PUSH:
            case WORKORDER_DYNAMIC_PUSH:
            case WORKORDER_DYNAMIC_UPDATE_PUSH:
            case WORKORDER_DYNAMIC_DEL_PUSH:
            case WORKORDER_NEW_EXECUTOR:
            case WORKORDER_NEW_EXECUTED:
            case WORKORDER_CONFIRM:
            case WORKORDER_TEAM:
            case WORKORDER_STAGE_COMPLETE:
            case WORKORDER_COMPLETE:
            case WORKORDER_CLOSE:
            case WORKORDER_RESTART:
            case WORKORDER_TRANSFER:
            case WORKORDER_ROLLBACK:
            case WORKORDER_COMMENT_LIKE_PUSH:
            case WORKORDER_COMMENT_PUSH:
            case WORKORDER_COMMENT_AT:
            case WORKORDER_COMMENT_DEL_PUSH:
            case PAYMENT_TASK_PUSH:
            case PAYMENT_TASK_ADD_PUSH:
            // 线索
            case CLUE_PUSH:
            case CLUE_ADD_PUSH:
            case CLUE_CHANGE_PUSH:
            case CLUE_TEAM_ADD_DEL_MAIN:
            case CLUE_TEAM_ADD_DEL_SYNERGETIC:
            case CLUE_STAGE:
            case CONTRACT_STAGE_PUSH:
            case CLUE_STAGE_TIMEOUT_REMIND_PUSH:
            case CUSTOMER_STAGE_TIMEOUT_REMIND_PUSH:
            case OPPORTUNITY_STAGE_TIMEOUT_REMIND_PUSH:
            case PAAS_STAGE_TIMEOUT_REMIND_PUSH:
            case CONTRACT_STAGE_TIMEOUT_REMIND_PUSH:
            case PAAS_STAGE:
            //工单2.0操作推送
            case WORK_ORDER_V2_PUSH:
            //工单2.0动态推送
            case WORK_ORDER_V2_DYNAMIC_PUSH:
            case WORK_ORDER_V2_COMMENT_AT:
            case WORKORDER_V2_COMMENT_LIKE_PUSH:
            case WORKORDER_V2_COMMENT_PUSH:
            case WORKORDER_V2_DYNAMIC_UPDATE_PUSH:
                PushRefTypePojo.CommonDetailOptions commonDetailOption = new PushRefTypePojo.CommonDetailOptions();
                BeanUtil.copyProperties(options, commonDetailOption);
                 optionMap = BeanUtil.convertBean2Map(commonDetailOption);
                pushRefTypePojo.setType(MessagePushRefTypeEnum.COMMON_DETAIL.getAlias());

                pushRefTypePojo.setPcUrl(formatPcUrl(MessageWebPcUrlEnum.COMMON_DETAIL.getUrl(), optionMap));
                pushRefTypePojo.setOptions(commonDetailOption);
                break;
            case CUSTOMER_BACK_PUBLIC:
            case CLUE_BACK_PUBLIC:
                //这个是退回公海池设置的
                break;
            case CUSTOMER_HANDOVER_PUSH:
            case CUSTOMER_DISTRIBUTION_PUSH:
            case CUSTOMER_BACK_PUSH:
            case CUSTOMER_WILL_BACK_PUSH:
            case CUSTOMER_TRANSFER_PUSH:
            case CUSTOMER_WILL_TRANSFER_PUSH:
                PushRefTypePojo.CommonListOptions commonListOptions = new PushRefTypePojo.CommonListOptions();
                BeanUtil.copyProperties(options, commonListOptions);
                optionMap = BeanUtil.convertBean2Map(commonListOptions);
                pushRefTypePojo.setType(MessageWebPcUrlEnum.CUSTOMER_LIST.getType());

                pushRefTypePojo.setPcUrl(formatPcUrl(MessageWebPcUrlEnum.CUSTOMER_LIST.getUrl(), optionMap));
                pushRefTypePojo.setOptions(commonListOptions);
                break;
            case CLUE_HANDOVER_PUSH:
            case CLUE_DISTRIBUTION_PUSH:
            case CLUE_BACK_PUSH:
            case CLUE_WILL_BACK_PUSH:
            case CLUE_TRANSFER_PUSH:
            case CLUE_WILL_TRANSFER_PUSH:
                PushRefTypePojo.CommonListOptions commonListOptions1 = new PushRefTypePojo.CommonListOptions();
                BeanUtil.copyProperties(options, commonListOptions1);
                optionMap = BeanUtil.convertBean2Map(commonListOptions1);
                pushRefTypePojo.setType(MessageWebPcUrlEnum.CLUE_LIST.getType());

                pushRefTypePojo.setPcUrl(formatPcUrl(MessageWebPcUrlEnum.CLUE_LIST.getUrl(), optionMap));
                pushRefTypePojo.setOptions(commonListOptions1);
                break;
            case DISTRIBUTOR_HANDOVER_PUSH:
                PushRefTypePojo.CommonListOptions listOptions = new PushRefTypePojo.CommonListOptions();
                listOptions.setDistributorMark(DistributorMarkEnum.DISTRIBUTOR.getCode());
                BeanUtil.copyProperties(options, listOptions);
                optionMap = BeanUtil.convertBean2Map(listOptions);
                pushRefTypePojo.setType(MessageWebPcUrlEnum.DISTRIBUTOR_LIST.getType());

                pushRefTypePojo.setPcUrl(formatPcUrl(MessageWebPcUrlEnum.DISTRIBUTOR_LIST.getUrl(), optionMap));
                pushRefTypePojo.setOptions(listOptions);
                break;
            //跟进消息
            case COMMUNICATE_PUSH:
            case COMMUNICATE_ADD_PUSH:
            case COMMUNICATE_LIKE_PUSH:
            case COMMUNICATE_COMMENT_PUSH:
            case COMMUNICATE_REPLY_PUSH:
            case COMMUNICATE_AT_PUSH:
            case COMMUNICATE_COMMENT_DEL_PUSH:
                PushRefTypePojo.SpecialDetailOptions specialDetailOptions = new PushRefTypePojo.SpecialDetailOptions();
                BeanUtil.copyProperties(options, specialDetailOptions);
                optionMap = BeanUtil.convertBean2Map(specialDetailOptions);
                pushRefTypePojo.setType(MessageWebPcUrlEnum.COMMUNICATE_DETAIL.getType());

                pushRefTypePojo.setPcUrl(formatPcUrl(MessageWebPcUrlEnum.COMMUNICATE_DETAIL.getUrl(), optionMap));
                pushRefTypePojo.setOptions(specialDetailOptions);
                break;
            //经销商跟进消息
            case DISTRIBUTOR_COMMUNICATE_PUSH:
            case DISTRIBUTOR_COMMUNICATE_ADD_PUSH:
            case DISTRIBUTOR_COMMUNICATE_LIKE_PUSH:
            case DISTRIBUTOR_COMMUNICATE_COMMENT_PUSH:
            case DISTRIBUTOR_COMMUNICATE_REPLY_PUSH:
            case DISTRIBUTOR_COMMUNICATE_AT_PUSH:
            case DISTRIBUTOR_COMMUNICATE_COMMENT_DEL_PUSH:
                specialDetailOptions = new PushRefTypePojo.SpecialDetailOptions();
                BeanUtil.copyProperties(options, specialDetailOptions);
                optionMap = BeanUtil.convertBean2Map(specialDetailOptions);
                pushRefTypePojo.setType(MessageWebPcUrlEnum.DISTRIBUTOR_COMMUNICATE_DETAIL.getType());

                pushRefTypePojo.setPcUrl(formatPcUrl(MessageWebPcUrlEnum.DISTRIBUTOR_COMMUNICATE_DETAIL.getUrl(), optionMap));
                pushRefTypePojo.setOptions(specialDetailOptions);
                break;
            case MARKETING_ACTIVITY_MANAGEMENT_ONLINE_PUSH:
            case PROMOTION_ACTIVITY_MANAGEMENT_ONLINE_PUSH:
                PushRefTypePojo.MarketingListOptions marketingListOptions = new PushRefTypePojo.MarketingListOptions();
                BeanUtil.copyProperties(options, marketingListOptions);
                optionMap = BeanUtil.convertBean2Map(marketingListOptions);
                pushRefTypePojo.setType(MessageWebPcUrlEnum.COMMON_DETAIL.getType());

                pushRefTypePojo.setPcUrl(formatPcUrl(MessageWebPcUrlEnum.COMMON_DETAIL.getUrl(), optionMap));
                pushRefTypePojo.setOptions(marketingListOptions);
                break;
            case PAYMENT_REMIND:
            case PAYMENT_OVERDUE:
                PushRefTypePojo.CommonListOptions paymentOptions = new PushRefTypePojo.CommonListOptions();
                BeanUtil.copyProperties(options, paymentOptions);
                optionMap = BeanUtil.convertBean2Map(paymentOptions);
                pushRefTypePojo.setType(MessageWebPcUrlEnum.COLLECTION_LIST.getType());
                pushRefTypePojo.setPcUrl(formatPcUrl(MessageWebPcUrlEnum.COLLECTION_LIST.getUrl(), optionMap));
                pushRefTypePojo.setOptions(paymentOptions);
                break;
            case PAY_PLAN_REMIND:
            case PAY_PLAN_OVERDUE:
                PushRefTypePojo.CommonListOptions payPlanOptions = new PushRefTypePojo.CommonListOptions();
                BeanUtil.copyProperties(options, payPlanOptions);
                optionMap = BeanUtil.convertBean2Map(payPlanOptions);
                pushRefTypePojo.setType(MessageWebPcUrlEnum.PAYMENT_LIST.getType());
                pushRefTypePojo.setPcUrl(formatPcUrl(MessageWebPcUrlEnum.PAYMENT_LIST.getUrl(), optionMap));
                pushRefTypePojo.setOptions(payPlanOptions);
                break;

            case SALE_REPORT_PUSH:
                PushRefTypePojo.SalesReportOptions salesReportOptions = new PushRefTypePojo.SalesReportOptions();
                BeanUtil.copyProperties(options, salesReportOptions);
                optionMap = BeanUtil.convertBean2Map(salesReportOptions);
                pushRefTypePojo.setType(MessageWebPcUrlEnum.SALE_REPORT.getType());
                pushRefTypePojo.setOptions(salesReportOptions);
                pushRefTypePojo.setPcUrl(formatPcUrl(MessageWebPcUrlEnum.SALE_REPORT.getUrl(), optionMap));
                break;
            case COMMUNICATE_PLAN_REMIND:
                break;
            case WORK_REPORT_PUSH:
                PushRefTypePojo.CommonListOptions workReportListOptions = new PushRefTypePojo.CommonListOptions();
                BeanUtil.copyProperties(options, workReportListOptions);
                optionMap = BeanUtil.convertBean2Map(workReportListOptions);
                pushRefTypePojo.setType(MessageWebPcUrlEnum.WORK_REPORT_LIST.getType());
                pushRefTypePojo.setOptions(workReportListOptions);
                pushRefTypePojo.setPcUrl(formatPcUrl(MessageWebPcUrlEnum.WORK_REPORT_LIST.getUrl(), optionMap));
                break;
            case WORK_REPORT_REMIND_PUSH:
                if (isCreator) {
                    PushRefTypePojo.CommonListOptions workReportRemindListOptions = new PushRefTypePojo.CommonListOptions();
                    BeanUtil.copyProperties(options, workReportRemindListOptions);
                    optionMap = BeanUtil.convertBean2Map(workReportRemindListOptions);
                    pushRefTypePojo.setType(MessageWebPcUrlEnum.WORK_REPORT_LIST.getType());
                    pushRefTypePojo.setOptions(workReportRemindListOptions);
                    pushRefTypePojo.setPcUrl(formatPcUrl(MessageWebPcUrlEnum.WORK_REPORT_LIST.getUrl(), optionMap));
                } else {
                    PushRefTypePojo.StatisticOptions workReportRemindStatisticOptions = new PushRefTypePojo.StatisticOptions();
                    BeanUtil.copyProperties(options, workReportRemindStatisticOptions);
                    optionMap = BeanUtil.convertBean2Map(workReportRemindStatisticOptions);
                    pushRefTypePojo.setOptions(workReportRemindStatisticOptions);
                    pushRefTypePojo.setType(MessageWebPcUrlEnum.WORK_REPORT_STATISTIC.getType());
                    pushRefTypePojo.setPcUrl(formatPcUrl(MessageWebPcUrlEnum.WORK_REPORT_STATISTIC.getUrl(), optionMap));
                }
                break;
            case WORK_REPORT_OVERDUE_PUSH:
                if (isCreator) {
                    PushRefTypePojo.CommonListOptions workReportOverDueListOptions = new PushRefTypePojo.CommonListOptions();
                    BeanUtil.copyProperties(options, workReportOverDueListOptions);
                    optionMap = BeanUtil.convertBean2Map(workReportOverDueListOptions);
                    pushRefTypePojo.setType(MessageWebPcUrlEnum.WORK_REPORT_LIST.getType());
                    pushRefTypePojo.setOptions(workReportOverDueListOptions);
                    pushRefTypePojo.setPcUrl(formatPcUrl(MessageWebPcUrlEnum.WORK_REPORT_LIST.getUrl(), optionMap));
                } else {
                    PushRefTypePojo.StatisticOptions workReportOverdueStatisticOptions = new PushRefTypePojo.StatisticOptions();
                    BeanUtil.copyProperties(options, workReportOverdueStatisticOptions);
                    optionMap = BeanUtil.convertBean2Map(workReportOverdueStatisticOptions);
                    pushRefTypePojo.setOptions(workReportOverdueStatisticOptions);
                    pushRefTypePojo.setType(MessageWebPcUrlEnum.WORK_REPORT_STATISTIC.getType());
                    pushRefTypePojo.setPcUrl(formatPcUrl(MessageWebPcUrlEnum.WORK_REPORT_STATISTIC.getUrl(), optionMap));
                }
                break;
            case WORK_REPORT_ADD_PUSH:
            case WORK_REPORT_COMMENT_PUSH:
            case WORK_REPORT_COMMENT_DEL_PUSH:
            case WORK_REPORT_COMMENT_LIKE_PUSH:
            case WORK_REPORT_AT_PUSH:
            case WORK_REPORT_COMMENT_UNREAD_PUSH:
                PushRefTypePojo.SpecialDetailOptions workReportOptions = new PushRefTypePojo.SpecialDetailOptions();
                BeanUtil.copyProperties(options, workReportOptions);
                // 21232 【工作报告】新建工作报告的时候填写抄送人，抄送人再CRM的系统打开记录，显示空白
                workReportOptions.setSubBusinessType(XbbRefTypeEnum.WORK_REPORT.getCode());
                optionMap = BeanUtil.convertBean2Map(workReportOptions);
                pushRefTypePojo.setType(MessageWebPcUrlEnum.WORK_REPORT_DETAIL.getType());

                pushRefTypePojo.setPcUrl(formatPcUrl(MessageWebPcUrlEnum.WORK_REPORT_DETAIL.getUrl(), optionMap));
                pushRefTypePojo.setOptions(workReportOptions);
                break;

            case SIGN_IN_ADD_PUSH:
                PushRefTypePojo.SpecialDetailOptions signInOptions = new PushRefTypePojo.SpecialDetailOptions();
                BeanUtil.copyProperties(options, signInOptions);
                optionMap = BeanUtil.convertBean2Map(signInOptions);
                pushRefTypePojo.setType(MessageWebPcUrlEnum.SIGN_IN_DETAIL.getType());

                pushRefTypePojo.setPcUrl(formatPcUrl(MessageWebPcUrlEnum.SIGN_IN_DETAIL.getUrl(), optionMap));
                pushRefTypePojo.setOptions(signInOptions);
                break;

            case APPROVAL_PUSH:
            case APPROVAL_ADD_PUSH:
            case APPROVAL_CHANGE_PUSH:
            case APPROVAL_NODE_CHANGE_PUSH:
            case APPROVAL_AGREE_PUSH:
            case APPROVAL_REFUSE_PUSH:
            case APPROVAL_REEDIT_PUSH:
            case APPROVAL_CARBON_COPY_PUSH:
            case APPROVAL_PUSH_ADD_COMMENT:
            case APPROVAL_COMMENT_AT:
            case APPROVAL_COMMENT_EDIT:
            case APPROVAL_COMMENT_DEL:
                PushRefTypePojo.WorkFlowListOptions approvalOptions = new PushRefTypePojo.WorkFlowListOptions();
                BeanUtil.copyProperties(options, approvalOptions);
                pushRefTypePojo.setType(MessageWebPcUrlEnum.APPROVE.getType());
                pushRefTypePojo.setOptions(approvalOptions);
                if (openWorkFlow) {
                    pushRefTypePojo.setPcUrl(MessageWebPcUrlEnum.WORKFLOW.getUrl());
                } else {
                    pushRefTypePojo.setPcUrl(MessageWebPcUrlEnum.APPROVE.getUrl());
                }
                break;

            case SFA_PUSH:
            case SFA_CUSTOMER_PUSH:
            case SFA_OPPORTUNITY_PUSH:
            case SFA_CONTRACT_PUSH:
            case SFA_CONTACT_PUSH:
                break;

            case SYSTEM_PUSH:
                break;
            case NEW_SIGNATURE_PUSH:
                break;
            case QUESTIONNAIRE_PUSH:
                break;
            case RENEW_PUSH:
                break;
            case ACTIVITY_OPERATION_PUSH:
                break;
            case INVITE_STAFF_PUSH:
                break;
            case EXPIRED_PUSH:
                break;
            case EXPORT_PUSH:
            case EXPORT_PUSH_FAIL:
                PushRefTypePojo.DownloadOptions downloadOptions = new PushRefTypePojo.DownloadOptions();
                BeanUtil.copyProperties(options, downloadOptions);
                pushRefTypePojo.setType(MessagePushRefTypeEnum.EXPORT.getAlias());
                pushRefTypePojo.setOptions(downloadOptions);
                pushRefTypePojo.setPcUrl(downloadOptions.getDownloadUrl());
                break;
            case DATA_WARNING_PUSH:
                PushRefTypePojo.DataWarningOptions dataWarningOptions = new PushRefTypePojo.DataWarningOptions();
                BeanUtil.copyProperties(options, dataWarningOptions);
                optionMap = BeanUtil.convertBean2Map(dataWarningOptions);
                pushRefTypePojo.setType(MessageWebPcUrlEnum.CHART_DATA_WARNING_LIST.getType());
                pushRefTypePojo.setOptions(dataWarningOptions);
                pushRefTypePojo.setPcUrl(formatPcUrl(MessageWebPcUrlEnum.CHART_DATA_WARNING_LIST.getUrl(), optionMap));
                break;
            case CUSTOMER_PUBLIC_POOL_MODEL_CHANGE_MESSAGE:
                PushRefTypePojo.CommonListOptions customerPulicGroup = new PushRefTypePojo.CommonListOptions();
                BeanUtil.copyProperties(options, customerPulicGroup);
                pushRefTypePojo.setType(MessageWebPcUrlEnum.CUSTOMER_PUBLIC_POOL_MODEL_CHANGE.getType());
                pushRefTypePojo.setOptions(customerPulicGroup);
                pushRefTypePojo.setPcUrl(MessageWebPcUrlEnum.CUSTOMER_PUBLIC_POOL_MODEL_CHANGE.getUrl());
                break;
            case CLUE_PUBLIC_POOL_MODEL_CHANGE_MESSAGE:
                PushRefTypePojo.CommonListOptions cluePublicGroup = new PushRefTypePojo.CommonListOptions();
                BeanUtil.copyProperties(options, cluePublicGroup);
                pushRefTypePojo.setType(MessageWebPcUrlEnum.CLUE_PUBLIC_POOL_MODEL_CHANGE.getType());
                pushRefTypePojo.setOptions(cluePublicGroup);
                pushRefTypePojo.setPcUrl(MessageWebPcUrlEnum.CLUE_PUBLIC_POOL_MODEL_CHANGE.getUrl());
                break;
            case DATA_IMPORT:
            case TRAIN_MODEL:
                /*PushRefTypePojo.CommonListOptions modelListOptions = new PushRefTypePojo.CommonListOptions();
                BeanUtil.copyProperties(options, modelListOptions);
                optionMap = BeanUtil.convertBean2Map(modelListOptions);
                pushRefTypePojo.setType(MessageWebPcUrlEnum.MODEL_LIST.getType());
                pushRefTypePojo.setOptions(modelListOptions);
                pushRefTypePojo.setPcUrl(formatPcUrl(MessageWebPcUrlEnum.MODEL_LIST.getUrl(), optionMap));*/
                break;
            case UNKNOWN:
                break;
            default:
        }
        return JSON.toJSONString(pushRefTypePojo);
    }

    /**
     * Description: 拼接push表中refType中的pcUrl字段
     * @param url 链接前缀
     * @param options 拼接用参数
     * @return java.lang.String
     * @author 魏荣杰
     * @date 2019/4/8 13:50
     * @since v1.0
     */
    private String formatPcUrl(String url, Map<String, Object> options) {
        String params = null;
        for (Map.Entry<String, Object> entry : options.entrySet()) {
            if (params == null) {
                params = entry.getKey() + "=" + entry.getValue();
            } else {
                params += "&" + entry.getKey() + "=" + entry.getValue();
            }
        }
        return url + "?" + params;
    }
    /**
     * Description: oa消息体封装
     * @param pushTypeEnum 消息类型
     * @param title 消息标题
     * @param content 消息内容
     * @param formList 消息form部分
     * @param options
     * @param corpid
     * @param openWorkFlow
     * @return com.alibaba.dingtalk.openapi.message.OAMessage
     * @author 魏荣杰
     * @date 2019/3/4 10:00
     * @since v1.0
     */
    private OA formatOaMessage(PushTypeEnum pushTypeEnum, String title, String content, List<OA.Body.Form> formList, PushRefTypePojo.Options options, String corpid, boolean isCreator, boolean openWorkFlow) {
        String messageUrl = proBaseConfig.getPushFrontUrl() + "index.html?corpid=" + corpid + "&appid=" + Env.DING_XBB_APP_ID + "&dd_nav_bgcolor=ffff943e#";
        String pcMessageUrl = "dingtalk://dingtalkclient/page/link?url=";
        OA oaMessage = new OA();
        OA.Body body = new OA.Body();
        body.setForm(formList);
        body.setTitle(title);
        body.setContent(content);
        body.setAuthor(I18nMessageUtil.getMessage(I18nStringConstant.XBB_CRM));
        oaMessage.setBody(body);
        //OA消息封装
        switch (pushTypeEnum) {
            case PAAS_STAGE:
            case PAAS_STAGE_TIMEOUT_REMIND_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.PAAS_FORM_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId(), options.getName());
                break;
            case CUSTOMER_PUSH:
            case CUSTOMER_ADD_PUSH:
            case CUSTOMER_CHANGE_PUSH:
            case CUSTOMER_BACK_PUBLIC:
            case CUSTOMER_TEAM_ADD_DEL_MAIN:
            case CUSTOMER_TEAM_ADD_DEL_SYNERGETIC:
            case CUSTOMER_REMIND:
            case CUSTOMER_STAGE:
            case CUSTOMER_STAGE_TIMEOUT_REMIND_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.CUSTOMER_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;
            case CUSTOMER_HANDOVER_PUSH:
            case CUSTOMER_DISTRIBUTION_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.CUSTOMER_LIST.getUrl(), options.getAppId(), options.getMenuId(), options.getFormId(), options.getDataIds());
                break;
            case CUSTOMER_BACK_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.CUSTOMER_PUBLIC_LIST.getUrl(), options.getAppId(), options.getMenuId(), options.getFormId(), options.getDataIds());
                break;
            case CUSTOMER_WILL_BACK_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.CUSTOMER_LIST.getUrl(), options.getAppId(), options.getMenuId(), options.getFormId(), options.getDataIds());
                break;
            case CONTACT_PUSH:
            case CONTACT_NEW:
                messageUrl += String.format(DingtalkPageUrlEnum.CONTACT_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;

            case OPPORTUNITY_PUSH:
            case OPPORTUNITY_ADD_PUSH:
            case OPPORTUNITY_CHANGE_PUSH:
            case OPPORTUNITY_TEAM_ADD_DEL_MAIN_PUSH:
            case OPPORTUNITY_TEAM_ADD_DEL_SYNERGETIC_PUSH:
            case OPPORTUNITY_EXPIRE_PUSH:
            case OPPORTUNITY_STAGE_PUSH:
            case OPPORTUNITY_STAGE_TIMEOUT_REMIND_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.OPPORTUNITY_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;

            case COMMUNICATE_PLAN_PUSH:
            case COMMUNICATE_PLAN_ADD_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.COMMUNICATE_PLAN_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;

            case COMMUNICATE_PUSH:
            case COMMUNICATE_ADD_PUSH:
            case COMMUNICATE_LIKE_PUSH:
            case COMMUNICATE_COMMENT_PUSH:
            case COMMUNICATE_REPLY_PUSH:
            case COMMUNICATE_AT_PUSH:
            case COMMUNICATE_COMMENT_DEL_PUSH:
                if (Objects.equals(options.getBusinessType(), XbbRefTypeEnum.CUSTOMER_COMMUNICATE.getCode())) {
                    messageUrl += String.format(DingtalkPageUrlEnum.COMMUNICATE_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                } else if (Objects.equals(options.getBusinessType(), XbbRefTypeEnum.SUPPLIER_COMMUNICATE.getCode())) {
                    messageUrl += String.format(DingtalkPageUrlEnum.JXC_COMMUNICATE_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                }
                break;

            case CONTRACT_PUSH:
            case CONTRACT_ADD_PUSH:
            case CONTRACT_CHANGE_PUSH:
            case CONTRACT_TEAM_ADD_DEL_MAIN_PUSH:
            case CONTRACT_TEAM_ADD_DEL_SYNERGETIC_PUSH:
            case CONTRACT_REMIND:
            case CONTRACT_STAGE_TIMEOUT_REMIND_PUSH:
            case CONTRACT_STAGE_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.CONTRACT_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;

            case PAYMENT_PLAN_ADD:
                messageUrl += String.format(DingtalkPageUrlEnum.PAYMENT_PLAN_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;
            case PAYMENT_SHEET_ADD:
            case PAYMENT_SHEET_BAD_ADD:
            case PAYMENT_SHEET_RED_ADD:
            case PAYMENT_SHEET_PREPAYMENT_ADD:
            case PAYMENT_SHEET_RED_PREPAYMENT_ADD:
                messageUrl += String.format(DingtalkPageUrlEnum.PAYMENT_SHEET_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;
            case PAY_SHEET_ADD:
            case PAY_SHEET_BAD_ADD:
            case PAY_SHEET_RED_ADD:
            case PAY_SHEET_PREPAY_ADD:
            case PAY_SHEET_RED_PREPAY_ADD:
                messageUrl += String.format(DingtalkPageUrlEnum.PAY_SHEET_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;

            case PAYMENT_REMIND:
                messageUrl += String.format(DingtalkPageUrlEnum.PAYMENT_PLAN_LIST.getUrl(), options.getAppId(), options.getMenuId(), options.getFormId(), options.getDataIds());
                oaMessage.getHead().setText(I18nMessageUtil.getMessage(I18nStringConstant.XBB_CRM_SEVEN_REMIND));
                break;
            case PAYMENT_OVERDUE:
                messageUrl += String.format(DingtalkPageUrlEnum.PAYMENT_PLAN_LIST.getUrl(), options.getAppId(), options.getMenuId(), options.getFormId(), options.getDataIds());
                oaMessage.getHead().setText(I18nMessageUtil.getMessage(I18nStringConstant.XBB_CRM_OVERDUE_REMIND));
                break;
            case PAY_PLAN_ADD:
                messageUrl += String.format(DingtalkPageUrlEnum.PAY_PLAN_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;
            case PAY_PLAN_REMIND:
                messageUrl += String.format(DingtalkPageUrlEnum.PAY_PLAN_LIST.getUrl(), options.getAppId(), options.getMenuId(), options.getFormId(), options.getDataIds());
                LOG.info("============================未付款链接："+messageUrl);
                oaMessage.getHead().setText("销帮帮CRM七天付款提醒");
                break;
            case PAY_PLAN_OVERDUE:
                messageUrl += String.format(DingtalkPageUrlEnum.PAY_PLAN_LIST.getUrl(), options.getAppId(), options.getMenuId(), options.getFormId(), options.getDataIds());
                LOG.info("============================逾期付款链接："+messageUrl);
                oaMessage.getHead().setText("销帮帮CRM七天付款提醒");
                break;
            case INVOICE_PUSH:
            case INVOICE_ADD_PUSH:
            case INVOICE_DEL_PUSH:
            case INVOICE_REDUCTION:
            case INVOICE_INVALIDATION:
            case INVOICE_RED_ADD_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.INVOICE_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;
            case PURCHASE_INVOICE_PUSH:
            case PURCHASE_INVOICE_ADD_PUSH:
            case PURCHASE_INVOICE_DEL_PUSH:
            case PURCHASE_INVOICE_REDUCTION:
            case PURCHASE_INVOICE_INVALIDATION:
            case PURCHASE_INVOICE_RED_ADD_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.PURCHASE_INVOICE_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;
            case SALE_REPORT_PUSH:
                oaMessage.getHead().setText(I18nMessageUtil.getMessage(I18nStringConstant.XBB_CRM_SALES_BRIEFING));
                String startTime = null;
                String endTime = null;
                Iterator<OA.Body.Form> iterator = formList.iterator();
                while (iterator.hasNext()) {
                    OA.Body.Form form = iterator.next();
                    if (Objects.equals(form.getKey(), "start")) {
                        startTime = form.getValue();
                        iterator.remove();
                    }
                    if (Objects.equals(form.getKey(), "end")) {
                        endTime = form.getValue();
                        iterator.remove();
                    }
                }
                body.setForm(formList);

                messageUrl += String.format(DingtalkPageUrlEnum.SALE_REPORT_DETAIL.getUrl(), startTime, endTime);
                break;
            case COMMUNICATE_PLAN_REMIND:
                //没用
                break;
            case WORK_REPORT_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.WORK_REPORT_LIST.getUrl(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;
            case WORK_REPORT_REMIND_PUSH:
            case WORK_REPORT_OVERDUE_PUSH:
                if (isCreator) {
                    messageUrl += String.format(DingtalkPageUrlEnum.WORK_REPORT_LIST.getUrl(), options.getAppId(), options.getMenuId(), options.getFormId());
                } else {
                    messageUrl += String.format(DingtalkPageUrlEnum.WORK_REPORT_STATISTIC.getUrl(), options.getReportDate(), options.getReportType(), options.getReportDate().get(0), options.getReportDate().get(1));
                }
                break;
            case WORK_REPORT_ADD_PUSH:
            case WORK_REPORT_COMMENT_PUSH:
            case WORK_REPORT_COMMENT_DEL_PUSH:
            case WORK_REPORT_COMMENT_LIKE_PUSH:
            case WORK_REPORT_AT_PUSH:
            case WORK_REPORT_COMMENT_UNREAD_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.WORK_REPORT_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId(), options.getSubBusinessType());
                break;

            case SIGN_IN_ADD_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.SIGN_IN_DETAIL.getUrl(), options.getDataId());
                break;
            case PURCHASE_PUSH:
            case PURCHASE_SUCCESS_PUSH:
            case PURCHASE_TEAM_ADD_DEL_MAIN_PUSH:
            case PURCHASE_TEAM_ADD_DEL_SYNERGETIC_PUSH:
            case WAIT_INSTOCK_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.PURCHASE_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;
            case INSTOCK_PUSH:
            case INSTOCK_SUCCESS_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.INSTOCK_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;
            case OUTSTOCK_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.OUTSTOCK_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;
            case OUTSTOCK_SUCCESS_PUSH:
            case WAIT_OUTSTOCK_PUSH:
            case WAIT_PURCHASE_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.CONTRACT_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;
            case SUPPLIER_PUSH:
            case SUPPLIER_ADD_PUSH:
            case SUPPLIER_TEAM_ADD_DEL_MAIN_PUSH:
            case SUPPLIER_TEAM_ADD_DEL_SYNERGETIC_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.SUPPLIER_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;
            case BOMBILL_PUSH:
            case BOMBILL_TEAM_ADD_DEL_MAIN_PUSH:
            case BOMBILL_TEAM_ADD_DEL_SYNERGETIC_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.BOMBILL_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;
            case PRODUCTION_ORDER_PUSH:
            case PRODUCTION_ORDER_TEAM_ADD_DEL_MAIN_PUSH:
            case PRODUCTION_ORDER_TEAM_ADD_DEL_SYNERGETIC_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.PRODUCTION_ORDER_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;
            /*case REFUND_PUSH:
            case REFUND_ADD_PUSH:
            case REFUND_ADD_WITH_PRODUCT_PUSH:
            case REFUND_ADD_WITHOUT_PRODUCT_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.REFUND_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;*/
            case RETURNED_PURCHASE_PUSH:
                //目前没在用
                break;
            case APPROVAL_PUSH:
            case APPROVAL_ADD_PUSH:
            case APPROVAL_CHANGE_PUSH:
            case APPROVAL_NODE_CHANGE_PUSH:
            case APPROVAL_AGREE_PUSH:
            case APPROVAL_REFUSE_PUSH:
            case APPROVAL_REEDIT_PUSH:
            case APPROVAL_CARBON_COPY_PUSH:
            case APPROVAL_PUSH_ADD_COMMENT:
            case APPROVAL_COMMENT_AT:
            case APPROVAL_COMMENT_EDIT:
            case APPROVAL_COMMENT_DEL:
                if (openWorkFlow) {
                    messageUrl += String.format(DingtalkPageUrlEnum.WORKFLOW_DETAIL.getUrl(), options.getProcessTaskId(), options.getProcessNodeTaskId(), options.getAppId(), options.getMenuId(), options.getFormId(), options.getSaasMark(), options.getBusinessType(), options.getProcessType());
                } else {
                    messageUrl += String.format(DingtalkPageUrlEnum.APPROVAL_DETAIL.getUrl(), options.getProcessTaskId(), options.getProcessNodeTaskId(), options.getAppId(), options.getMenuId(), options.getFormId(), options.getSaasMark(), options.getBusinessType(), options.getProcessType());
                }
                break;
            case WORKORDER_PUSH:
            case WORKORDER_DEL_PUSH:
            case WORKORDER_DYNAMIC_PUSH:
            case WORKORDER_DYNAMIC_UPDATE_PUSH:
            case WORKORDER_DYNAMIC_DEL_PUSH:
            case WORKORDER_NEW_EXECUTOR:
            case WORKORDER_NEW_EXECUTED:
            case WORKORDER_CONFIRM:
            case WORKORDER_TEAM:
            case WORKORDER_STAGE_COMPLETE:
            case WORKORDER_COMPLETE:
            case WORKORDER_CLOSE:
            case WORKORDER_RESTART:
            case WORKORDER_TRANSFER:
            case WORKORDER_ROLLBACK:
            case WORKORDER_COMMENT_LIKE_PUSH:
            case WORKORDER_COMMENT_PUSH:
            case WORKORDER_COMMENT_AT:
            case WORKORDER_COMMENT_DEL_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.WORK_ORDER_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;
            case SFA_PUSH:
                break;
            case SFA_CUSTOMER_PUSH:
                break;
            case SFA_OPPORTUNITY_PUSH:
                break;
            case SFA_CONTRACT_PUSH:
                break;
            case SFA_CONTACT_PUSH:
                break;
            case SYSTEM_PUSH:
                break;
            case NEW_SIGNATURE_PUSH:
                break;
            case QUESTIONNAIRE_PUSH:
                break;
            case RENEW_PUSH:
                break;
            case ACTIVITY_OPERATION_PUSH:
                break;
            case INVITE_STAFF_PUSH:
                //需要根据前端落地页方案，这边是登录逻辑
                messageUrl = proBaseConfig.getPushFrontUrl() + String.format(DingtalkPageUrlEnum.INVITE_STAFF_APP.getUrl(), corpid, Env.DING_XBB_APP_ID);
                //控制台打开
                String webIndex = proBaseConfig.getPushFrontUrl() + String.format(DingtalkPageUrlEnum.INVITE_STAFF_WEB.getUrl(), corpid, Env.DING_XBB_APP_ID);
                pcMessageUrl = "dingtalk://dingtalkclient/action/openapp?corpid=" + corpid + "&container_type=work_platform&app_id=" + Env.DING_XBB_APP_ID + "&redirect_type=jump&redirect_url=" + URLEncodeUtils.encodeURL(webIndex);
                break;
            case EXPIRED_PUSH:
                break;
            case EXPORT_PUSH:
            case EXPORT_PUSH_FAIL:
                messageUrl += String.format(DingtalkPageUrlEnum.DOWNLOAD_PAGE.getUrl(), options.getDownloadUrl(), DateTimeUtil.getInt() + 7 * 86400);
                break;
            case QUOTATION_PUSH:
            case QUOTATION_CHANGE_PUSH:
            case QUOTATION_ADD_PUSH:
            case QUOTATION_TEAM_ADD_DEL_MAIN_PUSH:
            case QUOTATION_TEAM_ADD_DEL_SYNERGETIC_PUSH:
            case QUOTATION_STATUS_PUSH:
            case QUOTATION_REMIND:
                messageUrl += String.format(DingtalkPageUrlEnum.QUOTATION_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;
            case PAYMENT_TASK_PUSH:
            case PAYMENT_TASK_ADD_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.PAYMENT_TASK_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;
            case DISTRIBUTOR_PUSH:
            case DISTRIBUTOR_ADD_PUSH:
            case DISTRIBUTOR_TEAM_ADD_DEL_MAIN:
            case DISTRIBUTOR_TEAM_ADD_DEL_SYNERGETIC:
                messageUrl += String.format(DingtalkPageUrlEnum.DISTRIBUTOR_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;
            case DISTRIBUTOR_HANDOVER_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.DISTRIBUTOR_LIST.getUrl(), options.getAppId(), options.getMenuId(), options.getFormId(), options.getDataIds());
                break;
            case DISTRIBUTOR_CONTACT_PUSH:
            case DISTRIBUTOR_CONTACT_ADD_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.DISTRIBUTOR_CONTACT_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;
            case DISTRIBUTOR_COMMUNICATE_PUSH:
            case DISTRIBUTOR_COMMUNICATE_ADD_PUSH:
            case DISTRIBUTOR_COMMUNICATE_LIKE_PUSH:
            case DISTRIBUTOR_COMMUNICATE_COMMENT_PUSH:
            case DISTRIBUTOR_COMMUNICATE_REPLY_PUSH:
            case DISTRIBUTOR_COMMUNICATE_AT_PUSH:
            case DISTRIBUTOR_COMMUNICATE_COMMENT_DEL_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.DISTRIBUTOR_COMMUNICATE_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;
            case ORDER_PUSH:
            case ORDER_ADD_PUSH:
            case ORDER_CHANGE_PUSH:
            case ORDER_TEAM_ADD_DEL_MAIN_PUSH:
            case ORDER_TEAM_ADD_DEL_SYNERGETIC_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.ORDER_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;
            case MARKETING_ACTIVITY_MANAGEMENT_PUSH:
            case MARKETING_ACTIVITY_MANAGEMENT_ONLINE_PUSH:
            case PROMOTION_ACTIVITY_MANAGEMENT_PUSH:
            case PROMOTION_ACTIVITY_MANAGEMENT_ONLINE_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.MARKETING_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getSubBusinessType(), options.getBusinessType(),options.getFormId());
                break;
            case STATEMENT_GENERATE_PUSH:
            case STATEMENT_QUESTION_FEEDBACK_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.STATEMENT_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;
            case CLUE_PUSH:
            case CLUE_ADD_PUSH:
            case CLUE_CHANGE_PUSH:
            case CLUE_BACK_PUBLIC:
            case CLUE_TEAM_ADD_DEL_MAIN:
            case CLUE_TEAM_ADD_DEL_SYNERGETIC:
            case CLUE_STAGE:
            case CLUE_STAGE_TIMEOUT_REMIND_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.CLUE_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;
            case CLUE_HANDOVER_PUSH:
            case CLUE_DISTRIBUTION_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.CLUE_LIST.getUrl(), options.getAppId(), options.getMenuId(), options.getFormId(), options.getDataIds());
                break;
            case CLUE_BACK_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.CLUE_PUBLIC_LIST.getUrl(), options.getAppId(), options.getMenuId(), options.getFormId(), options.getDataIds());
                break;
            case CLUE_WILL_BACK_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.CLUE_LIST.getUrl(), options.getAppId(), options.getMenuId(), options.getFormId(), options.getDataIds());
                break;
            case DATA_WARNING_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.DATA_WARNING_DETAIL.getUrl(), options.getChartId(), options.getCategoryId(),options.getDataWarningId());
                break;
            case DATA_IMPORT:
            case TRAIN_MODEL:
                messageUrl += String.format(DingtalkPageUrlEnum.INDEX.getUrl(), corpid);
                break;
            case CUSTOMER_PUBLIC_POOL_MODEL_CHANGE_MESSAGE:
                //特殊固定页面
                messageUrl += "/detail/seas-pool";
                break;
            case CLUE_PUBLIC_POOL_MODEL_CHANGE_MESSAGE:
                //特殊固定页面
                messageUrl += "/detail/seas-pool";
                break;
            //工单2.0操作推送
            case WORK_ORDER_V2_PUSH:
            //工单2.0动态推送
            case WORK_ORDER_V2_DYNAMIC_PUSH:
            case WORK_ORDER_V2_COMMENT_AT:
            case WORKORDER_V2_COMMENT_LIKE_PUSH:
            case WORKORDER_V2_COMMENT_PUSH:
            case WORKORDER_V2_DYNAMIC_UPDATE_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.WORK_ORDER_V2_DETAIL.getUrl(), options.getDataId(), options.getAppId(),
                        options.getMenuId(), options.getFormId(), options.getBusinessType(), options.getSaasMark(), options.getSubBusinessType());
                break;
            case UNKNOWN:
                break;
            default:
                messageUrl += String.format(DingtalkPageUrlEnum.INDEX.getUrl(), corpid);
                break;
        }

        //非邀请在右侧打开
        if (!Objects.equals(pushTypeEnum, PushTypeEnum.INVITE_STAFF_PUSH)) {
            pcMessageUrl += URLEncodeUtils.encodeURL(messageUrl) + "&pc_slide=true";
        }

        oaMessage.setMessageUrl(messageUrl);
        oaMessage.setPcMessageUrl(pcMessageUrl);

        return oaMessage;
    }

//    @Async(value = "messageThreadPool")
    @Override
    public void insertPushData(MessageRabbitMqDTO messageRabbitMqDTO, PushTypeEnum pushTypeEnum) throws XbbException {
        String corpid = messageRabbitMqDTO.getCorpid();
        List<String> userIds = messageRabbitMqDTO.getUserIds();
        List<Long> refIds = messageRabbitMqDTO.getRefIds();
        if (StringUtil.isEmpty(corpid)) {
            throw new XbbException(MessageErrorCodeEnum.API_ERROR_380007);
        }
        if (userIds == null || userIds.size() == 0) {
            throw new XbbException(MessageErrorCodeEnum.API_ERROR_380005);
        }
        if (userIds.size() > 100) {
            throw new XbbException(MessageErrorCodeEnum.API_ERROR_380008);
        }
        if (refIds == null || refIds.size() == 0) {
            throw new XbbException(MessageErrorCodeEnum.API_ERROR_380006);
        }

        Integer isRemind = messageRabbitMqDTO.getRemind();
        Long pushTime = messageRabbitMqDTO.getPushTime();
        String title = messageRabbitMqDTO.getTitle();
        String content = messageRabbitMqDTO.getContent();

        List<OA.Body.Form> formList = messageRabbitMqDTO.getForm();

        PushRefTypePojo.Options options = messageRabbitMqDTO.getOptions();

        boolean openWorkFlow = commonHelp.isOpenWorkFlow(corpid);

        OA oaMessage = formatOaMessage(pushTypeEnum, title, content, formList, options, corpid, false, openWorkFlow);

        String type = formatRefType(pushTypeEnum, options, false, openWorkFlow);

        Long now = DateTimeUtil.getInt();
        //以下备注的都是弃用的  @date 2019/2/26 19:37  @author 魏荣杰
        PushEntity pushEntity = new PushEntity();
        pushEntity.setCorpid(corpid);
        pushEntity.setRefEntity(pushTypeEnum.getCode());
        // TODO: 2019/3/1 refid 待优化
        pushEntity.setRefId(refIds.get(0));
        pushEntity.setRefArray(JSONObject.toJSONString(refIds));
        //用于标记web端消息跳转方式
        pushEntity.setRefType(type);
        pushEntity.setType(pushTypeEnum.getCode());
        pushEntity.setSubType(pushTypeEnum.getSubCode());
        pushEntity.setPushObject(JSONObject.toJSONString(userIds));
        pushEntity.setMsg(JSONObject.toJSONString(oaMessage));
        pushEntity.setPushTime(pushTime);
        pushEntity.setIsPush(0);
        pushEntity.setIsRemind(isRemind);
        pushEntity.setAddTime(now);
        pushEntity.setUpdateTime(now);
        pushService.save(pushEntity);
    }

    @Override
    public void insertListPushData(MessageRabbitMqDTO messageRabbitMqDTO, PushTypeEnum pushTypeEnum, String name) throws XbbException {
        String corpid = messageRabbitMqDTO.getCorpid();
        List<String> userIds = messageRabbitMqDTO.getUserIds();
        List<Long> refIds = messageRabbitMqDTO.getRefIds();
        if (StringUtil.isEmpty(corpid)) {
            throw new XbbException(MessageErrorCodeEnum.API_ERROR_380007);
        }
        if (userIds == null || userIds.size() == 0) {
            throw new XbbException(MessageErrorCodeEnum.API_ERROR_380005);
        }
        if (userIds.size() > 100) {
            throw new XbbException(MessageErrorCodeEnum.API_ERROR_380008);
        }
        if (refIds == null || refIds.size() == 0) {
            throw new XbbException(MessageErrorCodeEnum.API_ERROR_380006);
        }

        Integer isRemind = messageRabbitMqDTO.getRemind();
        Long pushTime = messageRabbitMqDTO.getPushTime();
        String title = messageRabbitMqDTO.getTitle();
        String content = messageRabbitMqDTO.getContent();

        List<OA.Body.Form> formList = messageRabbitMqDTO.getForm();

        PushRefTypePojo.Options options = messageRabbitMqDTO.getOptions();
        String messageUrl = proBaseConfig.getPushFrontUrl() + "index.html?corpid=" + corpid + "&appid=" + Env.DING_XBB_APP_ID + "&dd_nav_bgcolor=ffff943e#";
        String pcMessageUrl = "dingtalk://dingtalkclient/page/link?url=";
        OA oaMessage = new OA();

        String type = "";
        if (Objects.nonNull(options)) {
            oaMessage = SendMessageUtil.formatOaMessageDingtalkUrl(corpid, options.getSaasMark(), options.getBusinessType(), name,  title, content, formList, options,  messageUrl, pcMessageUrl);
            type = SendMessageUtil.formatRefTypeListUrl(options.getBusinessType(), options.getSaasMark(), options);
        }
        Long now = DateTimeUtil.getInt();
        PushEntity pushEntity = new PushEntity();
        pushEntity.setCorpid(corpid);
        pushEntity.setRefEntity(pushTypeEnum.getCode());
        pushEntity.setRefId(refIds.get(0));
        pushEntity.setRefArray(JSONObject.toJSONString(refIds));
        //用于标记web端消息跳转方式
        pushEntity.setRefType(type);
        pushEntity.setType(pushTypeEnum.getCode());
        pushEntity.setSubType(pushTypeEnum.getSubCode());
        pushEntity.setPushObject(JSONObject.toJSONString(userIds));
        pushEntity.setMsg(JSONObject.toJSONString(oaMessage));
        pushEntity.setPushTime(pushTime);
        pushEntity.setIsPush(0);
        pushEntity.setIsRemind(isRemind);
        pushEntity.setAddTime(now);
        pushEntity.setUpdateTime(now);
        pushService.save(pushEntity);
    }

    @Override
    public void insertDetailPushData(MessageRabbitMqDTO messageRabbitMqDTO, PushTypeEnum pushTypeEnum, String name) throws XbbException {
        String corpid = messageRabbitMqDTO.getCorpid();
        List<String> userIds = messageRabbitMqDTO.getUserIds();
        List<Long> refIds = messageRabbitMqDTO.getRefIds();
        if (StringUtil.isEmpty(corpid)) {
            throw new XbbException(MessageErrorCodeEnum.API_ERROR_380007);
        }
        if (userIds == null || userIds.size() == 0) {
            throw new XbbException(MessageErrorCodeEnum.API_ERROR_380005);
        }
        if (userIds.size() > 100) {
            throw new XbbException(MessageErrorCodeEnum.API_ERROR_380008);
        }
        if (refIds == null || refIds.size() == 0) {
            throw new XbbException(MessageErrorCodeEnum.API_ERROR_380006);
        }

        Integer isRemind = messageRabbitMqDTO.getRemind();
        Long pushTime = messageRabbitMqDTO.getPushTime();
        String title = messageRabbitMqDTO.getTitle();
        String content = messageRabbitMqDTO.getContent();

        List<OA.Body.Form> formList = messageRabbitMqDTO.getForm();

        PushRefTypePojo.Options options = messageRabbitMqDTO.getOptions();
        String messageUrl = proBaseConfig.getPushFrontUrl() + "index.html?corpid=" + corpid + "&appid=" + Env.DING_XBB_APP_ID + "&dd_nav_bgcolor=ffff943e#";
        String pcMessageUrl = "dingtalk://dingtalkclient/page/link?url=";
        OA oaMessage = new OA();

        String type = "";
        if (Objects.nonNull(options)) {
            oaMessage = SendMessageUtil.detailFormatOaMessage(corpid, options.getSaasMark(), options.getBusinessType(), name,  title, content, formList, options,  messageUrl, pcMessageUrl);
            type = SendMessageUtil.getDetail(options);
        }
        Long now = DateTimeUtil.getInt();
        PushEntity pushEntity = new PushEntity();
        pushEntity.setCorpid(corpid);
        pushEntity.setRefEntity(pushTypeEnum.getCode());
        pushEntity.setRefId(refIds.get(0));
        pushEntity.setRefArray(JSONObject.toJSONString(refIds));
        //用于标记web端消息跳转方式
        pushEntity.setRefType(type);
        pushEntity.setType(pushTypeEnum.getCode());
        pushEntity.setSubType(pushTypeEnum.getSubCode());
        pushEntity.setPushObject(JSONObject.toJSONString(userIds));
        pushEntity.setMsg(JSONObject.toJSONString(oaMessage));
        pushEntity.setPushTime(pushTime);
        pushEntity.setIsPush(0);
        pushEntity.setIsRemind(isRemind);
        pushEntity.setAddTime(now);
        pushEntity.setUpdateTime(now);
        pushService.save(pushEntity);
    }

    @Override
    public void sendToConversation(MessageSendToConversationDTO messageSendToConversationDTO) throws XbbException {
        String corpid = messageSendToConversationDTO.getCorpid();
        String cid = messageSendToConversationDTO.getCid();
        Integer businessType = messageSendToConversationDTO.getBusinessType();
        String refName = messageSendToConversationDTO.getRefName();
        Long dataId = messageSendToConversationDTO.getDataId();
        Long appId = messageSendToConversationDTO.getAppId();
        Long menuId = messageSendToConversationDTO.getMenuId();
        Long formId = messageSendToConversationDTO.getFormId();

        try {
            XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
            if (Objects.equals(xbbRefTypeEnum, XbbRefTypeEnum.UNKNOWN)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100018);
            }

            UserVO loginUser = messageSendToConversationDTO.getLoginUser();

            String title;
            String messageUrl = proBaseConfig.getPushFrontUrl() + "index.html?corpid=" + corpid + "&appid=" + Env.DING_XBB_APP_ID + "&dd_nav_bgcolor=ffff943e#";
            String pcMessageUrl = "dingtalk://dingtalkclient/page/link?url=";
            switch (xbbRefTypeEnum) {
                case CUSTOMER_MANAGEMENT:
                    CustomerEntityExt customerEntityExt = customerModel.getByKey(dataId, corpid);
                    title = "[" + I18nMessageUtil.getMessage(CommonConstant.CUSTOMER) + "]" + refName;
                    messageUrl += String.format(DingtalkPageUrlEnum.CUSTOMER_DETAIL.getUrl(), Long.toString(dataId), customerEntityExt.getAppId(), customerEntityExt.getMenuId(), customerEntityExt.getFormId());
                    break;
                case SALES_OPPORTUNITY:
                    OpportunityEntityExt opportunityEntityExt = opportunityModel.getByKey(dataId, corpid);
                    title = "[" + I18nMessageUtil.getMessage(CommonConstant.OPPORTUNITY) + "]" + refName;
                    messageUrl += String.format(DingtalkPageUrlEnum.OPPORTUNITY_DETAIL.getUrl(), Long.toString(dataId), opportunityEntityExt.getAppId(), opportunityEntityExt.getMenuId(), opportunityEntityExt.getFormId());
                    break;
                case CONTRACT:
                    ContractEntityExt contractEntityExt = contractModel.getByKey(dataId, corpid);
                    title = "[" + I18nMessageUtil.getMessage(CommonConstant.CONTRACT) + "]" + refName;
                    messageUrl += String.format(DingtalkPageUrlEnum.CONTRACT_DETAIL.getUrl(), Long.toString(dataId), contractEntityExt.getAppId(), contractEntityExt.getMenuId(), contractEntityExt.getFormId());
                    break;
                case PRODUCT:
                    ProductEntityExt productEntityExt = productModel.getByKey(dataId, corpid);
                    title = "[" + I18nMessageUtil.getMessage(CommonConstant.PRODUCT) + "]" + refName;
                    messageUrl += String.format(DingtalkPageUrlEnum.PRODUCT_DETAIL.getUrl(), Long.toString(dataId), productEntityExt.getAppId(), productEntityExt.getMenuId(), productEntityExt.getFormId());
                    break;
                default:
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100018);
            }
            pcMessageUrl += URLEncodeUtils.encodeURL(messageUrl) + "&pc_slide=true";

            OA oa = new OA();
            OA.Body body = new OA.Body();
            body.setTitle(title);
            body.setAuthor(loginUser.getName());
            oa.setBody(body);
            oa.setMessageUrl(messageUrl);
            oa.setPcMessageUrl(pcMessageUrl);
            Msg msg = new Msg(oa);

            SendToConversationHelper.SendToConversationResponse response = messageNewService.dingtalkSendToConversation(corpid, loginUser.getUserId(), cid, msg);
            if (Objects.nonNull(response)) {
                if (!Objects.equals(response.getErrcode(), 0L)) {
                    LOG.error("MessageServiceImpl.sendToConversation 失败， msg=" + JSON.toJSONString(response));
                    throw new XbbException(ErrorCodeEnum.API_FAIL);
                }
            }

        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("MessageServiceImpl.sendToConversation 失败", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }

    }

    @Override
    public void workReportRemindPush(MessageSaveAllTargetDataDTO messageSaveAllTargetDataDTO) throws XbbException {
        LOG.info("------------------------- 工作报告未交和逾期未交提醒数据入库 -> 定时任务 开始执行 --------------------------");
        LOG.info("========================= 工作报告未交和逾期未交提醒数据入库 定时任务执行开始时间：" + DateUtil.getInt() + " ==========================");
        String key = messageSaveAllTargetDataDTO.getKey();
        if (!Objects.equals(key, BasicConstant.TASK_SECRET_KEY)) {
            LOG.error("工作报告未交和逾期未交提醒数据入库 密码错误，停止定时任务！");
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100066);
        }
        Long todayInt = DateTimeUtil.getTodayInt();
        Long todayEndInt = DateTimeUtil.getTodayEndInt(todayInt);
        if (StringUtil.isNotEmpty(messageSaveAllTargetDataDTO.getOneCorpid())) {
            workReportBusinessToPush(messageSaveAllTargetDataDTO.getOneCorpid(),todayInt,todayEndInt);
            LOG.info("========================= 工作报告未交和逾期未交提醒数据入库 定时任务执行结束时间：" + DateUtil.getInt() + " ==========================");
            LOG.info("------------------------- 工作报告未交和逾期未交提醒数据入库 -> 定时任务 顺利结束 --------------------------");
            return;
        }
        Integer pageSize = 5000;
        Map<String, Object> param = new HashMap<>(16);
        param.put("del", 0);
        //正常使用
        param.put("status", 1);
        //开启了推送
        param.put("isPushMessage", 1);
        param.put("orderByStr", "add_time asc, corpid asc");
        param.put("columns", "corpid");
        Integer companyCount = companyModel.getEntitysCount(param);
        Integer threadNum = companyCount / pageSize + 1;
        for (int i = 1; i < threadNum + 1; i++) {
            Integer start = (i - 1) * pageSize;
            Integer pageNum = i * pageSize;

            param.put("start", start);
            param.put("pageNum", pageNum);
            List<CompanyEntity> companys = companyModel.findEntitys(param);
            for (CompanyEntity company : companys) {
                String corpid = company.getCorpid();
                workReportBusinessToPush(corpid,todayInt,todayEndInt);
            }
        }
        LOG.info("========================= 工作报告未交和逾期未交提醒数据入库 定时任务执行结束时间：" + DateUtil.getInt() + " ==========================");
        LOG.info("------------------------- 工作报告未交和逾期未交提醒数据入库 -> 定时任务 顺利结束 --------------------------");
    }

    private void setWorkReportRemindPush(String corpid, Integer type, PushSetEntity remindPushSetEntity, WorkReportSetEntity workReportSetEntity, Long appId, Long menuId) {
        Map<String, Object> dateMap = getWorkReportPush(type, workReportSetEntity, remindPushSetEntity);
        Long startDate = (Long) dateMap.get("startDate");
        Long endDate = (Long) dateMap.get("endDate");
        Long pushTime = (Long) dateMap.get("pushTime");
        boolean canPush = (boolean) dateMap.get("canPush");

        LOG.info("未交报告，canPush: {}",canPush);

        if (canPush) {
            // 符合未交报告提醒，消息入库
            List<PaasFormDataEntityExt> esEntities = null;
            try {
                BoolQueryBuilder filter = boolQuery()
                        .filter(termQuery("corpid.keyword", corpid))
                        .filter(termQuery("del", 0))
                        .filter(termsQuery("flowStatus", Arrays.asList(FlowStatusEnum.NOT_NEED_APPROVAL.getType(), FlowStatusEnum.PASS.getType())))
                        .filter(termQuery("data." + WorkReportFieldEnum.TYPE.getAttr() + ".keyword", type))
                        .filter(rangeQuery("data." + WorkReportFieldEnum.REPORT_DATE.getAttr()).gte(startDate).lt(endDate));
                List<String> fieldList = new ArrayList<>();
                fieldList.add(FieldTypeEnum.DATAID.getAlias());
                esEntities = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_WORK_REPORT, filter, PaasFormDataEntityExt.class, fieldList);
            } catch (XbbException e) {
                LOG.error("messageServiceimpl.setWorkReportRemindPush 查询工作报告出错 corpid = " + corpid);
            }
            Set<String> creators = new HashSet<>();
            if (CollectionsUtil.isNotEmpty(esEntities)) {
                Set<Long> ids = new HashSet<>();
                for (PaasFormDataEntityExt esEntity : esEntities) {
                    ids.add(esEntity.getDataId());
                }
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid", corpid);
                param.put("del", 0);
                param.put("ids", ids);
                List<WorkReportEntityExt> entitys = workReportModel.findEntitys(param);

                for (WorkReportEntityExt entityExt : entitys) {
                    creators.add(entityExt.getCreatorId());
                }
            }

            LOG.info("未交报告：提交人列表: {}",creators);

            JSONObject remindPushObject = JSONObject.parseObject(remindPushSetEntity.getPushObject());
            endDate -= TimeConstant.SECONDS_PER_DAY;
            List<String> filterArr = Arrays.asList(DateTimeUtil.getStringEpochSecond(startDate, DateTimeUtil.SDFDate), DateTimeUtil.getStringEpochSecond(endDate, DateTimeUtil.SDFDate));
            PushRefTypePojo.Options options = new PushRefTypePojo.Options(appId, menuId, null, SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.WORK_REPORT.getCode(), filterArr, type);

            List<String> unSubmitUser = new ArrayList<>();

            List<String> pushUserIdList = new ArrayList<>();

            String typeString = remindPushObject.getString("type");
            JSONArray typeJsonArray = JsonHelperUtil.parseArray(typeString);
            Set<String> visiableRange = getVisiableRange(workReportSetEntity, corpid);
            String messageContent = "";
            if (CollectionsUtil.isNotEmpty(visiableRange)) {
                for (String user : visiableRange) {
                    if (!creators.contains(user)) {
                        unSubmitUser.add(user);
                    }
                }
                Set<String> unSubmitPushList = getWorkSubmitUserPushList(visiableRange, unSubmitUser, remindPushObject);
                for (Object object : typeJsonArray) {
                    JSONObject jsonObject = (JSONObject) object;
                    Integer enable = jsonObject.getInteger("enable");
                    if (Objects.equals(enable, 1)) {
                        if (CollectionsUtil.isNotEmpty(unSubmitUser)) {
                            messageContent = getWorkReportPushContent(type, true, false, startDate, endDate, 0);
                            // 提交人，消息落地页是跳转到工作报告列表页
                            MessageRabbitMqDTO creatorMessageRabbitMqDTO = new MessageRabbitMqDTO(corpid, unSubmitUser, Collections.singletonList(0L), 0, pushTime, I18nMessageUtil.getMessage(WorkReportPushConstant.WORK_REPORT_SOON_OVERDUE_TITLE), messageContent, null, options);

                            try {
                                insertPushData(creatorMessageRabbitMqDTO, PushTypeEnum.WORK_REPORT_REMIND_PUSH, true);
                            } catch (XbbException e) {
                                LOG.error("MessageServiceImpl.setWorkReportRemindPush insertPushData出错,corpid= " + corpid + ", message= " + creatorMessageRabbitMqDTO.toString(), e);
                            }
                        }

                    }
                }
                Map<String, Object> paramUser = new HashMap<>(16);
                paramUser.put("corpid", corpid);
                paramUser.put("del", 0);
                paramUser.put("userIdIn", unSubmitPushList);
                List<UserEntity> userEntityList = userModel.findEntitys(paramUser);
                for (UserEntity userEntity : userEntityList) {
                    pushUserIdList = pushHelper.getPushUserIdList(userEntity, remindPushSetEntity.getPushObject(), pushUserIdList, null);
                }
            }
            UserEntity userEntity = new UserEntity();
            userEntity.setCorpid(corpid);
            userEntity.setDepartment("[]");
            pushUserIdList = pushHelper.getPushUserIdList(userEntity, remindPushSetEntity.getPushObject(), pushUserIdList, null);

            LOG.info("未交报告，推送人列表: {}",pushUserIdList);

            if (CollectionsUtil.isNotEmpty(pushUserIdList) && CollectionsUtil.isNotEmpty(unSubmitUser)) {
                messageContent = getWorkReportPushContent(type, false, false, startDate, endDate, unSubmitUser.size());
                // 其他人员是跳转到工作报告统计页
                MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserIdList, Collections.singletonList(0L), 0, pushTime, I18nMessageUtil.getMessage(WorkReportPushConstant.WORK_REPORT_SOON_OVERDUE_TITLE), messageContent, null, options);

                try {
                    insertPushData(messageRabbitMqDTO, PushTypeEnum.WORK_REPORT_REMIND_PUSH, false);
                } catch (XbbException e) {
                    LOG.error("MessageServiceImpl.setWorkReportRemindPush insertPushData出错,corpid= " + corpid + ", message= " + messageRabbitMqDTO.toString(), e);
                }
            }

        }
    }

    private void setWorkReportOverduePush(String corpid, Integer type, PushSetEntity overduePushSetEntity, WorkReportSetEntity workReportSetEntity, Long appId, Long menuId) {
        Map<String, Object> dateMap = getWorkReportPush(type, workReportSetEntity, overduePushSetEntity);
        Long startDate = (Long) dateMap.get("startDate");
        Long endDate = (Long) dateMap.get("endDate");
        Long pushTime = (Long) dateMap.get("pushTime");
        boolean canPush = (boolean) dateMap.get("canPush");

        LOG.info("逾期未交报告，canPush: {}",canPush);

        if (canPush) {
            // 符合逾期报告提醒，消息入库
            List<PaasFormDataEntityExt> esEntities = null;
            try {
                BoolQueryBuilder filter = boolQuery()
                        .filter(termQuery("corpid.keyword", corpid))
                        .filter(termQuery("del", 0))
                        .filter(termsQuery("flowStatus", Arrays.asList(FlowStatusEnum.NOT_NEED_APPROVAL.getType(), FlowStatusEnum.PASS.getType())))
                        .filter(termQuery("data." + WorkReportFieldEnum.TYPE.getAttr() + ".keyword", type))
                        .filter(rangeQuery("data." + WorkReportFieldEnum.REPORT_DATE.getAttr()).gte(startDate).lt(endDate));
                List<String> fieldList = new ArrayList<>();
                fieldList.add(FieldTypeEnum.DATAID.getAlias());
                esEntities = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_WORK_REPORT, filter, PaasFormDataEntityExt.class, fieldList);
            } catch (XbbException e) {
                LOG.error("messageServiceimpl.setWorkReportOverduePush 查询工作报告出错 corpid = " + corpid);
            }
            Set<String> creators = new HashSet<>();
            if (CollectionsUtil.isNotEmpty(esEntities)) {
                Set<Long> ids = new HashSet<>();
                for (PaasFormDataEntityExt esEntity : esEntities) {
                    ids.add(esEntity.getDataId());
                }
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid", corpid);
                param.put("del", 0);
                param.put("ids", ids);
                List<WorkReportEntityExt> entitys = workReportModel.findEntitys(param);

                for (WorkReportEntityExt entityExt : entitys) {
                    creators.add(entityExt.getCreatorId());
                }
            }

            LOG.info("逾期未交报告：提交人列表: {}",creators);

            JSONObject remindPushObject = JSONObject.parseObject(overduePushSetEntity.getPushObject());
            endDate -= TimeConstant.SECONDS_PER_DAY;
            List<String> filterArr = Arrays.asList(DateTimeUtil.getStringEpochSecond(startDate, DateTimeUtil.SDFDate), DateTimeUtil.getStringEpochSecond(endDate, DateTimeUtil.SDFDate));
            PushRefTypePojo.Options options = new PushRefTypePojo.Options(appId, menuId, null, SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.WORK_REPORT.getCode(), filterArr, type);

            List<String> unSubmitUser = new ArrayList<>();

            List<String> pushUserIdList = new ArrayList<>();

            String typeString = remindPushObject.getString("type");
            JSONArray typeJsonArray = JsonHelperUtil.parseArray(typeString);
            Set<String> visiableRange = getVisiableRange(workReportSetEntity, corpid);

            String messageContent = "";
            if (CollectionsUtil.isNotEmpty(visiableRange)) {
                for (String user : visiableRange) {
                    if (!creators.contains(user)) {
                        unSubmitUser.add(user);
                    }
                }
                Set<String> unSubmitPushList = getWorkSubmitUserPushList(visiableRange, unSubmitUser, remindPushObject);
                for (Object object : typeJsonArray) {
                    JSONObject jsonObject = (JSONObject) object;
                    Integer enable = jsonObject.getInteger("enable");
                    if (Objects.equals(enable, 1)) {
                        if (CollectionsUtil.isNotEmpty(unSubmitUser)) {
                            messageContent = getWorkReportPushContent(type, true, true, startDate, endDate, 0);
                            // 提交人，消息落地页是跳转到工作报告列表页
                            MessageRabbitMqDTO creatorMessageRabbitMqDTO = new MessageRabbitMqDTO(corpid, unSubmitUser, Collections.singletonList(0L), 0, pushTime, I18nMessageUtil.getMessage(WorkReportPushConstant.WORK_REPORT_OVERDUE_TITLE), messageContent, null, options);

                            try {
                                insertPushData(creatorMessageRabbitMqDTO, PushTypeEnum.WORK_REPORT_OVERDUE_PUSH, true);
                            } catch (XbbException e) {
                                LOG.error("MessageServiceImpl.setWorkReportRemindPush insertPushData出错,corpid= " + corpid + ", message= " + creatorMessageRabbitMqDTO.toString(), e);
                            }
                        }



                    }
                }
                Map<String, Object> paramUser = new HashMap<>(16);
                paramUser.put("corpid", corpid);
                paramUser.put("del", 0);
                paramUser.put("userIdIn", unSubmitPushList);
                List<UserEntity> userEntityList = userModel.findEntitys(paramUser);
                for (UserEntity userEntity : userEntityList) {
                    pushUserIdList = pushHelper.getPushUserIdList(userEntity, overduePushSetEntity.getPushObject(), pushUserIdList, null);
                }
            }

            UserEntity userEntity = new UserEntity();
            userEntity.setCorpid(corpid);
            userEntity.setDepartment("[]");
            pushUserIdList = pushHelper.getPushUserIdList(userEntity, overduePushSetEntity.getPushObject(), pushUserIdList, null);

            LOG.info("逾期未交报告，推送人列表: {}",pushUserIdList);

            if (CollectionsUtil.isNotEmpty(pushUserIdList) && CollectionsUtil.isNotEmpty(unSubmitUser)) {
                messageContent = getWorkReportPushContent(type, false, true, startDate, endDate, unSubmitUser.size());
                // 其他人员是跳转到工作报告统计页
                MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserIdList, Collections.singletonList(0L), 0, pushTime, I18nMessageUtil.getMessage(WorkReportPushConstant.WORK_REPORT_OVERDUE_TITLE), messageContent, null, options);

                try {
                    insertPushData(messageRabbitMqDTO, PushTypeEnum.WORK_REPORT_OVERDUE_PUSH, false);
                } catch (XbbException e) {
                    LOG.error("MessageServiceImpl.setWorkReportRemindPush insertPushData出错,corpid= " + corpid + ", message= " + messageRabbitMqDTO.toString(), e);
                }
            }

        }
    }

    /***
     * 获取工作报告未提交的人
     * @param visiableRange 工作报告有权限的人
     * @param unSubmitUser 未提交的人
     * @param remindPushObject 配置信息
     * @return
     */
    private Set<String> getWorkSubmitUserPushList(Set<String> visiableRange,List<String> unSubmitUser,JSONObject remindPushObject){
        //最终要推送的人主管
        Set<String> finalPushUserSet = new HashSet<>();
        JSONObject manager = remindPushObject.getJSONObject("manager");
        //是否仅仅推送给未提交人的主管
        boolean isJustCheckSelf = manager.getBooleanValue("justCheckSelf");
        if(isJustCheckSelf){
            finalPushUserSet.addAll(unSubmitUser);
        }else {
            finalPushUserSet.addAll(visiableRange);
        }
        return finalPushUserSet;
    }

    public void insertPushData(MessageRabbitMqDTO messageRabbitMqDTO, PushTypeEnum pushTypeEnum, boolean isCreator) throws XbbException {
        String corpid = messageRabbitMqDTO.getCorpid();
        List<String> userIds = messageRabbitMqDTO.getUserIds();
        List<Long> refIds = messageRabbitMqDTO.getRefIds();
        if (StringUtil.isEmpty(corpid)) {
            throw new XbbException(MessageErrorCodeEnum.API_ERROR_380007);
        }
        if (userIds == null || userIds.size() == 0) {
            throw new XbbException(MessageErrorCodeEnum.API_ERROR_380005);
        }
        if (userIds.size() > 100) {
            throw new XbbException(MessageErrorCodeEnum.API_ERROR_380008);
        }
        if (refIds == null || refIds.size() == 0) {
            throw new XbbException(MessageErrorCodeEnum.API_ERROR_380006);
        }

        Integer isRemind = messageRabbitMqDTO.getRemind();
        Long pushTime = messageRabbitMqDTO.getPushTime();
        String title = messageRabbitMqDTO.getTitle();
        String content = messageRabbitMqDTO.getContent();

        List<OA.Body.Form> formList = messageRabbitMqDTO.getForm();

        PushRefTypePojo.Options options = messageRabbitMqDTO.getOptions();

        boolean openWorkFlow = commonHelp.isOpenWorkFlow(corpid);

        OA oaMessage  = formatOaMessage(pushTypeEnum, title, content, formList, options, corpid, isCreator, openWorkFlow);

        String type = formatRefType(pushTypeEnum, options, isCreator, openWorkFlow);

        Long now = DateTimeUtil.getInt();
        //以下备注的都是弃用的  @date 2019/2/26 19:37  @author 魏荣杰
        PushEntity pushEntity = new PushEntity();
        pushEntity.setCorpid(corpid);
        pushEntity.setRefEntity(pushTypeEnum.getCode());
        pushEntity.setRefId(refIds.get(0));
        pushEntity.setRefArray(JSONObject.toJSONString(refIds));
        //用于标记web端消息跳转方式
        pushEntity.setRefType(type);
        pushEntity.setType(pushTypeEnum.getCode());
        pushEntity.setSubType(pushTypeEnum.getSubCode());
        pushEntity.setPushObject(JSONObject.toJSONString(userIds));
        pushEntity.setMsg(JSONObject.toJSONString(oaMessage));
        pushEntity.setPushTime(pushTime);
        pushEntity.setIsPush(0);
        pushEntity.setIsRemind(isRemind);
        pushEntity.setAddTime(now);
        pushEntity.setUpdateTime(now);
        pushService.save(pushEntity);
    }

    /**
     * 获取工作报告可见范围
     *
     * @param workReportSetEntity
     * @param corpid
     * @throws
     * @author long.rao
     * @date 2020-07-24 19:32
     */
    private Set<String> getVisiableRange(WorkReportSetEntity workReportSetEntity, String corpid) {
        Set<String> users = new HashSet<>();

        List<OptionalRangeEntity> visibleObject = new ArrayList<>();
        if (workReportSetEntity.getVisibleObject() != null) {
            try {
                visibleObject = workReportSetEntity.getVisibleObject().toJavaList(OptionalRangeEntity.class);
            } catch (JSONException e) {
                visibleObject = new ArrayList<>();
            }
        }

        //是否可见
        List<Integer> roles = new ArrayList<>();
        List<Long> userDepartmentList = new ArrayList<>();
        Boolean allDep = false;
        for (OptionalRangeEntity rangeEntity : visibleObject) {
            String property = rangeEntity.getProperty();
            String id = rangeEntity.getId();
            if (OptionalRangeEnum.DEPT.getValue().equals(property)) {
                userDepartmentList.add(Long.parseLong(id));
                if (Objects.equals(Long.parseLong(id), 1L)) {
                    allDep = true;
                }
            } else if (OptionalRangeEnum.ROLE.getValue().equals(property)) {
                roles.add(Integer.parseInt(id));
            } else if (OptionalRangeEnum.USER.getValue().equals(property)) {
                users.add(id);
            }
        }
        Set<Long> userAllDepartmentList = new HashSet<>();

        List<DepartmentEntity> allDepartment = new ArrayList<>();
        try {
            allDepartment = departmentModel.findAllDepartment(corpid, false);
        } catch (Exception e) {
            LOG.error("部门获取失败error：", e);
        }
        if (allDepartment != null && allDepartment.size() > 0 && userDepartmentList.size() > 0) {
            for (Long depId : userDepartmentList) {
                userAllDepartmentList.addAll(getSubDepIdList(depId, allDepartment));
            }
        }

        //全公司
        if ((users.size() == 0 && roles.size() == 0 && userDepartmentList.size() == 0) || allDep) {
            Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            map.put("corpid", corpid);
            map.put("del", DelEnum.NORMAL.getDel());
            List<String> userIds = userModel.getUserIds(map);
            return new HashSet<>(userIds);
        }
        //角色的userIds
        if (!roles.isEmpty()) {
            List<String> roleUserIds = userModel.getUserIdsByRoles(corpid, roles);
            users.addAll(roleUserIds);
        }
        //部门userIds
        if (!userDepartmentList.isEmpty()) {
            List<String> depUserIdList = userModel.getDepUserIdList(corpid, userAllDepartmentList, 0);
            users.addAll(depUserIdList);
        }
        return users;
    }

    /**
     * 获取部门id路由对应的部门
     * @param depId 部门id
     * @param departmentList 部门列表
     * @return
     */
    public Set<Long> getSubDepIdList(Long depId, List<DepartmentEntity> departmentList) {
        Set<Long> subDepIdList = new LinkedHashSet<>();
        DepartmentEntity department = null;

        for (DepartmentEntity entity : departmentList) {
            if (entity.getId().equals(depId)) {
                department = entity;
                break;
            }
        }

        if (department != null) {
            String router = department.getDepIdRouter();
            for (DepartmentEntity entity : departmentList) {
                if (entity.getDepIdRouter().contains(router)) {
                    subDepIdList.add(entity.getId());
                }
            }
        }

        if (subDepIdList.isEmpty()) {
            subDepIdList.add(depId);
        }

        return subDepIdList;
    }

    /**
     * 获取工作报告推送消息content
     *
     * @param type
     * @param isCreator
     * @param diOverdue
     * @param startTime
     * @param endTime
     * @param unSubmitSize
     * @throws
     * @author long.rao
     * @date 2020-07-24 19:31
     */
    private String getWorkReportPushContent(Integer type, boolean isCreator, boolean diOverdue, Long startTime, Long endTime, Integer unSubmitSize) {
        String messageContent = "";
        WorkReportTypeEnum workReportTypeEnum = WorkReportTypeEnum.getByType(type);
        String startTimeStr = "";
        String endTimeStr = "";
        switch (workReportTypeEnum){
            case DAILY:
                startTimeStr = DateTimeUtil.getStringEpochSecond(startTime, DateTimeUtil.SDFDate);
                if (isCreator) {
                    if (diOverdue) {
                        messageContent = WorkReportPushConstant.WORK_REPORT_OVERDUE_DAY_CONTENT;
                    } else {
                        messageContent = WorkReportPushConstant.WORK_REPORT_SOON_OVERDUE_DAY_CONTENT;
                    }
                    messageContent = String.format(I18nMessageUtil.getMessage(messageContent), startTimeStr);
                } else {
                    if (diOverdue) {
                        messageContent = WorkReportPushConstant.WORK_REPORT_OTHER_OVERDUE_DAY_CONTENT;
                    } else {
                        messageContent = WorkReportPushConstant.WORK_REPORT_OTHER_SOON_OVERDUE_DAY_CONTENT;
                    }
                    messageContent = String.format(I18nMessageUtil.getMessage(messageContent), unSubmitSize, startTimeStr);
                }

                break;
            case WEEKLY:
                startTimeStr = DateTimeUtil.getStringEpochSecond(startTime, DateTimeUtil.SDFDate);
                endTimeStr = DateTimeUtil.getStringEpochSecond(endTime, DateTimeUtil.SDFDate);
                startTimeStr = startTimeStr + "--" + endTimeStr;
                if (isCreator) {
                    if (diOverdue) {
                        messageContent = WorkReportPushConstant.WORK_REPORT_OVERDUE_WEEK_CONTENT;
                    } else {
                        messageContent = WorkReportPushConstant.WORK_REPORT_SOON_OVERDUE_WEEK_CONTENT;
                    }
                    messageContent = String.format(I18nMessageUtil.getMessage(messageContent), startTimeStr);
                } else {
                    if (diOverdue) {
                        messageContent = WorkReportPushConstant.WORK_REPORT_OTHER_OVERDUE_WEEK_CONTENT;
                    } else {
                        messageContent = WorkReportPushConstant.WORK_REPORT_OTHER_SOON_OVERDUE_WEEK_CONTENT;
                    }
                    messageContent = String.format(I18nMessageUtil.getMessage(messageContent), unSubmitSize, startTimeStr);
                }
                break;
            case MONTHLY:
                startTimeStr = DateTimeUtil.getStringEpochSecond(startTime, DateTimeUtil.SDFDate);
                endTimeStr = DateTimeUtil.getStringEpochSecond(endTime , DateTimeUtil.SDFDate);
                startTimeStr = startTimeStr + "--" + endTimeStr;
                if (isCreator) {
                    if (diOverdue) {
                        messageContent = WorkReportPushConstant.WORK_REPORT_OVERDUE_MONTH_CONTENT;
                    } else {
                        messageContent = WorkReportPushConstant.WORK_REPORT_SOON_OVERDUE_MONTH_CONTENT;
                    }
                    messageContent = String.format(I18nMessageUtil.getMessage(messageContent), startTimeStr);
                } else {
                    if (diOverdue) {
                        messageContent = WorkReportPushConstant.WORK_REPORT_OTHER_OVERDUE_MONTH_CONTENT;
                    } else {
                        messageContent = WorkReportPushConstant.WORK_REPORT_OTHER_SOON_OVERDUE_MONTH_CONTENT;
                    }
                    messageContent = String.format(I18nMessageUtil.getMessage(messageContent), unSubmitSize, startTimeStr);
                }
                break;
            default:
                break;
        }
        return messageContent;
    }

    private Map<String, Object> getWorkReportPush(Integer type, WorkReportSetEntity workReportSetEntity, PushSetEntity pushSetEntity) {
        Map<String, Object> dateMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        boolean canPush = false;
        Long startDate = 0L;
        Long endDate = 0L;

        JSONObject pushTimeObject = JSONObject.parseObject(pushSetEntity.getPushTime());
        Integer timeType = pushTimeObject.getInteger("timeType");
        Integer period = pushTimeObject.getInteger("period");
        Long busTime = DateTimeUtil.getTodayInt();
        if (Objects.equals(PushTimeTypeEnum.DELAYED.getCode(), timeType)) {
            busTime = busTime - period;
        }

        String pushTimeStr = pushTimeObject.getString("pushTime");
        String[] hourMinuteList = pushTimeStr.split(StringConstant.COLON);
        Integer hour = Integer.valueOf(hourMinuteList[0]);
        Integer minute = Integer.valueOf(hourMinuteList[1]);
        Long pushTime = DateTimeUtil.getTodayInt() + hour * TimeConstant.SECONDS_PER_HOUR + minute * TimeConstant.SECONDS_PER_MINUTE;

        String nowTimeStr = DateTimeUtil.getStringEpochSecond(DateTimeUtil.getInt(), DateTimeUtil.SDFHour_Minutes);

        String[] nowTimeHourMinuteList = nowTimeStr.split(StringConstant.COLON);
        Integer nowTimeHour = Integer.valueOf(nowTimeHourMinuteList[0]);
        nowTimeHour += 1;
        if (!Objects.equals(nowTimeHour, hour)) {
            // 因为推送时间只可以选9:00-24:00,所以可以这样判断
            // 当前时间早于推送时间一个钟头才触发处理推送的逻辑
            dateMap.put("startDate", startDate);
            dateMap.put("endDate", endDate);
            dateMap.put("canPush", canPush);
            dateMap.put("pushTime", pushTime);
            return dateMap;
        }

        Integer deadlineOption = workReportSetEntity.getDeadlineOption() == null ? 1 : workReportSetEntity.getDeadlineOption();
        WorkReportTypeEnum workReportTypeEnum = WorkReportTypeEnum.getByType(type);
        WorkReportDeadDayTypeEnum deadDayTypeEnum = WorkReportDeadDayTypeEnum.getByCodeType(deadlineOption, workReportTypeEnum.getType());


        switch (workReportTypeEnum){
            case DAILY:
                switch (deadDayTypeEnum){
                    case TODAY:
                        //本日
                        canPush = true;
                        break;
                    case TOMORROW:
                        //次日
                        canPush = true;
                        busTime -= TimeConstant.SECONDS_PER_DAY;
                        break;
                    default:
                        break;
                }
                startDate = DateTimeUtil.getTodayInt(busTime);
                endDate = startDate + TimeConstant.SECONDS_PER_DAY;
                break;
            case WEEKLY:
                int week = DateTimeUtil.getWeekInSomeday(busTime);
                switch (deadDayTypeEnum){
                    case FRIDAY:
                        //周五
                        if (week == 5) {
                            canPush = true;
                        }
                        break;
                    case SATURDAY:
                        //周六
                        if (week == 6) {
                            canPush = true;
                        }
                        break;
                    case SUNDAY:
                        //本日
                        if (week == 0) {
                            canPush = true;
                        }
                        break;
                    case MONDAY:
                        //下周一
                        if (week == 1) {
                            canPush = true;
                        }
                        break;
                    default:
                        break;
                }
                startDate = DateTimeUtil.getWeekMorningInSomeday(busTime);
                endDate = startDate + TimeConstant.SECONDS_PER_WEEK;
                break;
            case MONTHLY:

                switch (deadDayTypeEnum){
                    case FIRST_DAY_OF_NEXT_MONTH:
                        //次月第一天
                        if (Objects.equals(DateTimeUtil.getFirstDateOfMonthInSomeday(busTime), busTime)) {
                            canPush = true;
                            startDate = DateTimeUtil.getFirstDateOfLastMonth(busTime);
                            endDate = DateTimeUtil.getLastDateOfLastMonth(busTime);

                        }
                        break;
                    case LAST_DAY_OF_MONTH:
                        //当月最后一天
                        busTime = busTime + TimeConstant.SECONDS_PER_DAY;
                        if (Objects.equals(PushTimeTypeEnum.NOW.getCode(), timeType)) {
                            if (Objects.equals(DateTimeUtil.getLastDateOfThisMonth(), busTime)) {
                                canPush = true;
                                startDate = DateTimeUtil.getFirstDateOfLastMonth(busTime);
                                endDate = DateTimeUtil.getLastDateOfThisMonth();
                            }
                        } else if (Objects.equals(PushTimeTypeEnum.DELAYED.getCode(), timeType)) {
                            if (Objects.equals(DateTimeUtil.getLastDateOfLastMonth(busTime), busTime)) {
                                canPush = true;
                                startDate = DateTimeUtil.getFirstDateOfLastMonth(busTime);
                                endDate = DateTimeUtil.getLastDateOfLastMonth(busTime);
                            }
                        }
                        break;
                    default:
                        break;
                }
                break;
            default:
                break;
        }
        dateMap.put("startDate", startDate);
        dateMap.put("endDate", endDate);
        dateMap.put("canPush", canPush);
        dateMap.put("pushTime", pushTime);
        return dateMap;
    }

    /**
     * 校验当天推送数据是否生成
     *
     * @param corpid 公司corpid
     * @param pushTypeEnum 推送业务类型
     * @return
     */
    private boolean pushCheck(String corpid, PushTypeEnum pushTypeEnum) {
        Long todayInt = DateTimeUtil.getTodayInt();
        Long todayEndInt = DateTimeUtil.getTodayEndInt(todayInt);
        List<Long> idList = pushModel.getAlreadyProduceId(corpid, todayInt, todayEndInt, pushTypeEnum.getSubCode(), pushTypeEnum.getCode());
        return CollectionsUtil.isNotEmpty(idList);
    }
}
